From David.OShea at quantum.com Thu Nov 1 23:54:22 2012 From: David.OShea at quantum.com (David OShea) Date: Fri, 2 Nov 2012 03:54:22 +0000 Subject: [lttng-dev] 'add-context --userspace' must be preceded by 'enable-channel' or 'enable-event' In-Reply-To: <509039ED.6020203@efficios.com> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F843FE@ZURMSG1.QUANTUM.com> <20121030014845.GB26711@Krystal> <509039ED.6020203@efficios.com> Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F8515D@ZURMSG1.QUANTUM.com> Hi David, Mathieu, > -----Original Message----- > From: David Goulet [mailto:dgoulet at efficios.com] > Sent: Wednesday, 31 October 2012 7:05 AM > To: Mathieu Desnoyers > Cc: David OShea; lttng-dev at lists.lttng.org > Subject: Re: [lttng-dev] 'add-context --userspace' must be preceded by > 'enable-channel' or 'enable-event' [...] > Mathieu Desnoyers: > > If I understand correctly, the two use-cases where you issue > > "add-context" prior to enable-event and prior to enable-channel are > > behaving as if they are failing (those contexts don't appear in the > > trace), but you don't get any error message. David (David Goulet, in > > CC), any clue on why lttng-tools behaves that way, and how can we fix > > this ? This is not quite correct: I don't have a use case where I 'add-context' prior to 'enable-channel'. The only case that fails is when I do an 'add-context' immediately after 'create'. Things work properly if I do an 'enable-channel' or 'enable-event' before the 'add-context'. > >> Bad: 'add-context' before 'enable-event': > >> > >> """ > >> # lttng create > >> Session auto-20121029-090142 created. > >> Traces will be written in /root/lttng-traces/auto-20121029-090142 > >> # lttng add-context --userspace -t vpid -t vtid -t procname > >> UST context procname added to all channels > >> UST context vtid added to all channels > >> UST context vpid added to all channels > >> # lttng enable-event --userspace --all > > The context is added to "channel0" here which is the default one > created > automatically. > > The lttng-tools session daemon do add the contexts to the channel on > the > tracer side (ustctl_add_context) so Mathieu we might want to check if > the UST tracer do behave correctly by adding the context to all events > of a channel. (Note here that -a -u was used hence the "*" event). > > I also do confirm that lttng-tools is doing the right ustctl call on > channel0 here. I took a quick look at the source for lttng-tools 2.0.4 and 2.1.0-rc4, and it looks to me like in the case above, the default channel "channel0" is not actually created by 'add-context'. In lttng_enable_event(), if no channel name was specified, it uses DEFAULT_CHANNEL_NAME, then in cmd_enable_event_all() (I'm considering the case of enabling all events, which is what I do), in case LTTNG_DOMAIN_UST, if the specified channel doesn't exist, it will create it. This seems to be why doing the 'enable-event' first works. On the other hand, in lttng_add_context(), if no channel name is specified, no channel name is passed to the server, then in cmd_add_context(), context_ust_add() is called, and in that function, if no channel name is specified, it adds the context to every channel. However, my understanding is that at this point there are no channels created. Apologies if I have missed anything here! Regards, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From dgoulet at efficios.com Fri Nov 2 11:12:35 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 02 Nov 2012 11:12:35 -0400 Subject: [lttng-dev] 'add-context --userspace' must be preceded by 'enable-channel' or 'enable-event' In-Reply-To: <20998D40D9A2B7499CA5A3A2666CB1EB19F8515D@ZURMSG1.QUANTUM.com> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F843FE@ZURMSG1.QUANTUM.com> <20121030014845.GB26711@Krystal> <509039ED.6020203@efficios.com> <20998D40D9A2B7499CA5A3A2666CB1EB19F8515D@ZURMSG1.QUANTUM.com> Message-ID: <5093E2E3.7090601@efficios.com> Hi David, Yes you are right. I've opened a bug for that. You might want to subscribe to it :). https://bugs.lttng.org/issues/391 Thanks a lot! David David OShea: > Hi David, Mathieu, > >> -----Original Message----- >> From: David Goulet [mailto:dgoulet at efficios.com] >> Sent: Wednesday, 31 October 2012 7:05 AM >> To: Mathieu Desnoyers >> Cc: David OShea; lttng-dev at lists.lttng.org >> Subject: Re: [lttng-dev] 'add-context --userspace' must be preceded by >> 'enable-channel' or 'enable-event' > [...] >> Mathieu Desnoyers: >>> If I understand correctly, the two use-cases where you issue >>> "add-context" prior to enable-event and prior to enable-channel are >>> behaving as if they are failing (those contexts don't appear in the >>> trace), but you don't get any error message. David (David Goulet, in >>> CC), any clue on why lttng-tools behaves that way, and how can we fix >>> this ? > > This is not quite correct: I don't have a use case where I 'add-context' prior to 'enable-channel'. The only case that fails is when I do an 'add-context' immediately after 'create'. Things work properly if I do an 'enable-channel' or 'enable-event' before the 'add-context'. > >>>> Bad: 'add-context' before 'enable-event': >>>> >>>> """ >>>> # lttng create >>>> Session auto-20121029-090142 created. >>>> Traces will be written in /root/lttng-traces/auto-20121029-090142 >>>> # lttng add-context --userspace -t vpid -t vtid -t procname >>>> UST context procname added to all channels >>>> UST context vtid added to all channels >>>> UST context vpid added to all channels >>>> # lttng enable-event --userspace --all >> >> The context is added to "channel0" here which is the default one >> created >> automatically. >> >> The lttng-tools session daemon do add the contexts to the channel on >> the >> tracer side (ustctl_add_context) so Mathieu we might want to check if >> the UST tracer do behave correctly by adding the context to all events >> of a channel. (Note here that -a -u was used hence the "*" event). >> >> I also do confirm that lttng-tools is doing the right ustctl call on >> channel0 here. > > I took a quick look at the source for lttng-tools 2.0.4 and 2.1.0-rc4, and it looks to me like in the case above, the default channel "channel0" is not actually created by 'add-context'. > > In lttng_enable_event(), if no channel name was specified, it uses DEFAULT_CHANNEL_NAME, then in cmd_enable_event_all() (I'm considering the case of enabling all events, which is what I do), in case LTTNG_DOMAIN_UST, if the specified channel doesn't exist, it will create it. This seems to be why doing the 'enable-event' first works. > > On the other hand, in lttng_add_context(), if no channel name is specified, no channel name is passed to the server, then in cmd_add_context(), context_ust_add() is called, and in that function, if no channel name is specified, it adds the context to every channel. However, my understanding is that at this point there are no channels created. > > Apologies if I have missed anything here! > > Regards, > David > > ---------------------------------------------------------------------- > The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From dgoulet at efficios.com Fri Nov 2 11:17:29 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 02 Nov 2012 11:17:29 -0400 Subject: [lttng-dev] [PATCH lttng-tools] Tests: Add filtering tests for uncovered cases In-Reply-To: <1351688445-18551-1-git-send-email-christian.babeux@efficios.com> References: <1351688445-18551-1-git-send-email-christian.babeux@efficios.com> Message-ID: <5093E409.3070708@efficios.com> Merged! Thanks Christian Babeux: > While investigating the code coverage of the filtering feature, > a couple of possible tests cases were uncovered: > > Error tests: > * Strings can't be IR root node > * Unary ! not allowed on string type > * Comparison with string type not allowed > * Logical operator not allowed with string types > * Nesting of binary operator not allowed > > Valid tests: > * Cover all left/right operands permutations with > fields ref. and numeric values. > > Signed-off-by: Christian Babeux > --- > tests/tools/filtering/invalid-filters | 15 +++++++++++++++ > tests/tools/filtering/valid-filters | 4 ++++ > 2 files changed, 19 insertions(+) > > diff --git a/tests/tools/filtering/invalid-filters b/tests/tools/filtering/invalid-filters > index d0777e5..b653705 100755 > --- a/tests/tools/filtering/invalid-filters > +++ b/tests/tools/filtering/invalid-filters > @@ -118,6 +118,21 @@ INVALID_FILTERS=( > "!a.f.d" > "asdf.asdfsd.sadf < 4" > "asdfasdf->asdfasdf < 2" > + # String can't be root node > + "\"somestring\"" > + # Unary op on string not allowed > + "!\"somestring\"" > + # Comparison with string type not allowed > + "\"somestring\" > 42" > + "\"somestring\" > 42.0" > + "42 > \"somestring\"" > + "42.0 > \"somestring\"" > + # Logical operator with string type not allowed > + "\"somestring\" || 1" > + "1 || \"somestring\"" > + # Nesting of binary operator not allowed > + "1 | (1 | (1 | 1))" > + "1 > (1 > (1 > 1))" > ) > > start_lttng_sessiond > diff --git a/tests/tools/filtering/valid-filters b/tests/tools/filtering/valid-filters > index b48b6ed..d32a60d 100755 > --- a/tests/tools/filtering/valid-filters > +++ b/tests/tools/filtering/valid-filters > @@ -361,6 +361,8 @@ FILTERS=("intfield" #1 > "intfield < 0x2" #24 > "intfield < 02" #25 > "stringfield2 == \"\\\*\"" #26 > + "1.0 || intfield || 1.0" #27 > + "1 < intfield" #28 > ) > > VALIDATOR=("validator_intfield" #1 > @@ -389,6 +391,8 @@ VALIDATOR=("validator_intfield" #1 > "validator_intfield_lt" #24 > "validator_intfield_lt" #25 > "validator_true_statement" #26 > + "validator_true_statement" #27 > + "validator_intfield_gt" #28 > ) > > FILTER_COUNT=${#FILTERS[@]} From dgoulet at efficios.com Fri Nov 2 11:55:03 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 02 Nov 2012 11:55:03 -0400 Subject: [lttng-dev] [RELEASE] LTTng-tools 2.1.0-rc6 Message-ID: <5093ECD7.5080805@efficios.com> Greetings everyone (including LTTng elves), The lttng-tools project provides a session daemon (lttng-sessiond) that acts as a tracing registry, the "lttng" command line for tracing control, a lttng-ctl library for tracing control and a lttng-relayd for network streaming. The biggest changes was the lttng_data_available() API call renamed to lttng_data_pending() with the returned code semantic changed. In a nutshell, if data_pending returns 0, it means that all data was extracted from the buffers of the tracing session hence the trace is _ready_ to be read. Else, a value of 1 means that data is still pending for the tracing session so the trace is not readable. Apart from that, 30+ fixes got in mostly fixing memory leaks. Here is the ChangeLog: 2012-11-02 lttng-tools 2.1.0-rc6 * Tests: Add filtering tests for uncovered cases * Fix: Sync issue when deleting a data stream * Rename data_available to data_pending * Fix: consumer health state * Fix: Add the ACCOUNTING flag to ht creation and set bucket size to 0 * Fix: Bad return error code handling * Fix: Use after free() of the rundir string * Fix: Cleanup UST app session on ustctl create session error * Fix: add missing pthread_join in sessiond * Fix: free running directory string * Fix: UST app clean list node usage * Add liblttng-ctl destructor to cleanup memory * Fix: Cleanup URIs on teardown * Fix: relayd memleaks * Fix: Memory leaks of allocated URIs * Fix: consumer output memory leak on creation * Fix: missing addrlen initialization before accept(2) * Fix: relayd trace file padding memleak * Fix: Remove useless consumer subdir string concatenation * Fix: lttng create allocated path memleak * Fix: Cppcheck memleakOnRealloc mistake * Fix: Synchronization issue for data available command * Fix: consumer relayd cleanup on disconnect * Fix: Handle the unary bitwise negation operator (~) in the XML printer * Fix: Possible memory leaks when creating filter IR root node * Fix: Delete stream on write error in consumer * Fix: Error handling when sending relayd sockets to consumer * Add stream lock comment for nesting * Fix: Mutex and RCU lock nesting in consumer * Fix: Uninitialized ret code * Fix: Remove bad condition and fix overflow issue * Fix: consumerd pthread error flow * Fix: Set a single return point and mutex unlock * Fix: Remove useless NULL and zero assignment * Fix: segfault on create session with two URLs Please feel free to email the list about any questions/comments concerning this release. Project website: http://lttng.org/lttng2.0 Download link: http://lttng.org/files/lttng-tools/lttng-tools-2.1.0-rc6.tar.bz2 (for the PGP signature, same file with .asc appended) Cheers! David From christian.babeux at efficios.com Fri Nov 2 15:03:17 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Fri, 2 Nov 2012 15:03:17 -0400 Subject: [lttng-dev] [PATCH lttng-tools] Fix: Missing librt dependency in configure check for lttng-ust-ctl Message-ID: <1351882997-23283-1-git-send-email-christian.babeux@efficios.com> The lttng-ust-ctl library depends on librt. The AC_CHECK_LIBRARY macro can't automatically resolve dependents libraries (ala libtool), so any additionnals dependencies must be manually specified. Signed-off-by: Christian Babeux --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0911b9a..72daf7e 100644 --- a/configure.ac +++ b/configure.ac @@ -144,7 +144,7 @@ AS_IF([test "x$lttng_ust_support" = "xyes"], [ lttng_ust_ctl_found=yes ], [AC_MSG_ERROR([Cannot find LTTng-UST. Use [LDFLAGS]=-Ldir to specify its location, or specify --disable-lttng-ust to build lttng-tools without LTTng-UST support.])], - [-lurcu-common -lurcu-bp -lurcu-cds] + [-lurcu-common -lurcu-bp -lurcu-cds -lrt] ) ]) AM_CONDITIONAL([HAVE_LIBLTTNG_UST_CTL], [test "x$lttng_ust_ctl_found" = xyes]) -- 1.8.0 From christian.babeux at efficios.com Fri Nov 2 15:04:02 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Fri, 2 Nov 2012 15:04:02 -0400 Subject: [lttng-dev] [PATCH lttng-tools] Fix: Remove dependency to urcu-cds in tools tests Message-ID: <1351883042-23390-1-git-send-email-christian.babeux@efficios.com> The -lurcu-cds link flag is not mandatory to link any of the tests. Also, adding this flag can cause multiple symbol definition errors when linking statically because the libhashtable contains symbol names that are also present in urcu-cds. Signed-off-by: Christian Babeux --- tests/tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am index 56eda3a..cd7ff32 100644 --- a/tests/tools/Makefile.am +++ b/tests/tools/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = streaming filtering health AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_srcdir)/tests -g -Wall -AM_LDFLAGS = -lurcu -lurcu-cds +AM_LDFLAGS = -lurcu EXTRA_DIST = runall.sh -- 1.8.0 From mathieu.desnoyers at efficios.com Sun Nov 4 15:22:05 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 4 Nov 2012 15:22:05 -0500 Subject: [lttng-dev] [RFC PATCH urcu] Implement RCU lock free concurrent queue Message-ID: <20121104202205.GA28373@Krystal> Queue with lock-free semantic for both enqueue and dequeue. This queue requires the RCU read-side lock to be held around enqueue and around dequeue. This queue guarantees correct queue behavior even if a thread using the queue dies at any point (except of course for RCU read-side lock related issues that may arise in that case, but that is a separate issue). The improvement of rculfcqueue vs the existing rculfqueue: the new queue splits head and tail into 2 different objects, so users can put them into different cache lines, and thus eliminate false-sharing between head and tail. Similarly to the prior implementation, rculfcqueue dequeuer allocates dummy nodes to deal with the empty queue scenario. The only reason why this implementation allocates dummy nodes is because all my attempts to come up with a portable lock-free queue design that does not require dummy nodes have failed so far. Besides dummy node allocation, another downside of the lock-free queue compared to the wait-free/blocking queue is that implementing "splice" is not straightforward, because when splicing a chain of nodes into a destination queue, if the tail pointer update fails due to a concurrent enqueue, then other enqueuers will have to push the tail pointer over all nodes newly spliced in. This unpredictable delay on enqueue is not acceptable, so no splice operation is implemented. Signed-off-by: Mathieu Desnoyers CC: Paul E. McKenney CC: Lai Jiangshan --- diff --git a/Makefile.am b/Makefile.am index 195b89a..85a9263 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,7 @@ nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ urcu/rculist.h urcu/rcuhlist.h urcu/system.h urcu/futex.h \ urcu/uatomic/generic.h urcu/arch/generic.h urcu/wfstack.h \ urcu/wfqueue.h urcu/rculfstack.h urcu/rculfqueue.h \ + urcu/rculfcqueue.h \ urcu/ref.h urcu/cds.h urcu/urcu_ref.h urcu/urcu-futex.h \ urcu/uatomic_arch.h urcu/rculfhash.h urcu/wfcqueue.h \ urcu/lfstack.h \ @@ -74,6 +75,7 @@ liburcu_bp_la_SOURCES = urcu-bp.c urcu-pointer.c $(COMPAT) liburcu_bp_la_LIBADD = liburcu-common.la liburcu_cds_la_SOURCES = rculfqueue.c rculfstack.c lfstack.c \ + rculfcqueue.c \ $(RCULFHASH) $(COMPAT) liburcu_cds_la_LIBADD = liburcu-common.la diff --git a/tests/Makefile.am b/tests/Makefile.am index b029377..e04b847 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,8 +16,10 @@ noinst_PROGRAMS = test_urcu test_urcu_dynamic_link test_urcu_timing \ test_urcu_lfq test_urcu_wfq test_urcu_lfs test_urcu_wfs \ test_urcu_lfs_rcu \ test_urcu_wfcq \ + test_urcu_lfcq \ test_urcu_wfq_dynlink test_urcu_wfs_dynlink \ test_urcu_wfcq_dynlink \ + test_urcu_lfcq_dynlink \ test_urcu_lfq_dynlink test_urcu_lfs_dynlink test_urcu_hash \ test_urcu_lfs_rcu_dynlink \ test_urcu_multiflavor test_urcu_multiflavor_dynlink @@ -167,6 +169,13 @@ test_urcu_lfq_dynlink_SOURCES = test_urcu_lfq.c $(URCU) test_urcu_lfq_dynlink_CFLAGS = -DDYNAMIC_LINK_TEST $(AM_CFLAGS) test_urcu_lfq_dynlink_LDADD = $(URCU_CDS_LIB) +test_urcu_lfcq_SOURCES = test_urcu_lfcq.c $(URCU) +test_urcu_lfcq_LDADD = $(URCU_CDS_LIB) + +test_urcu_lfcq_dynlink_SOURCES = test_urcu_lfcq.c $(URCU) +test_urcu_lfcq_dynlink_CFLAGS = -DDYNAMIC_LINK_TEST $(AM_CFLAGS) +test_urcu_lfcq_dynlink_LDADD = $(URCU_CDS_LIB) + test_urcu_wfq_SOURCES = test_urcu_wfq.c $(COMPAT) test_urcu_wfq_LDADD = $(URCU_COMMON_LIB) diff --git a/tests/test_urcu_lfcq.c b/tests/test_urcu_lfcq.c new file mode 100644 index 0000000..2058aef --- /dev/null +++ b/tests/test_urcu_lfcq.c @@ -0,0 +1,463 @@ +/* + * test_urcu_lfcq.c + * + * Userspace RCU library - example RCU-based lock-free concurrent queue + * + * Copyright February 2010 - Mathieu Desnoyers + * Copyright February 2010 - Paolo Bonzini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define _GNU_SOURCE +#include "../config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef __linux__ +#include +#endif + +/* hardcoded number of CPUs */ +#define NR_CPUS 16384 + +#if defined(_syscall0) +_syscall0(pid_t, gettid) +#elif defined(__NR_gettid) +static inline pid_t gettid(void) +{ + return syscall(__NR_gettid); +} +#else +#warning "use pid as tid" +static inline pid_t gettid(void) +{ + return getpid(); +} +#endif + +#ifndef DYNAMIC_LINK_TEST +#define _LGPL_SOURCE +#endif +#include +#include + +static volatile int test_go, test_stop; + +static unsigned long rduration; + +static unsigned long duration; + +/* read-side C.S. duration, in loops */ +static unsigned long wdelay; + +static inline void loop_sleep(unsigned long loops) +{ + while (loops-- != 0) + caa_cpu_relax(); +} + +static int verbose_mode; + +#define printf_verbose(fmt, args...) \ + do { \ + if (verbose_mode) \ + printf(fmt, args); \ + } while (0) + +static unsigned int cpu_affinities[NR_CPUS]; +static unsigned int next_aff = 0; +static int use_affinity = 0; + +pthread_mutex_t affinity_mutex = PTHREAD_MUTEX_INITIALIZER; + +#ifndef HAVE_CPU_SET_T +typedef unsigned long cpu_set_t; +# define CPU_ZERO(cpuset) do { *(cpuset) = 0; } while(0) +# define CPU_SET(cpu, cpuset) do { *(cpuset) |= (1UL << (cpu)); } while(0) +#endif + +static void set_affinity(void) +{ +#if HAVE_SCHED_SETAFFINITY + cpu_set_t mask; + int cpu, ret; +#endif /* HAVE_SCHED_SETAFFINITY */ + + if (!use_affinity) + return; + +#if HAVE_SCHED_SETAFFINITY + ret = pthread_mutex_lock(&affinity_mutex); + if (ret) { + perror("Error in pthread mutex lock"); + exit(-1); + } + cpu = cpu_affinities[next_aff++]; + ret = pthread_mutex_unlock(&affinity_mutex); + if (ret) { + perror("Error in pthread mutex unlock"); + exit(-1); + } + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); +#if SCHED_SETAFFINITY_ARGS == 2 + sched_setaffinity(0, &mask); +#else + sched_setaffinity(0, sizeof(mask), &mask); +#endif +#endif /* HAVE_SCHED_SETAFFINITY */ +} + +/* + * returns 0 if test should end. + */ +static int test_duration_dequeue(void) +{ + return !test_stop; +} + +static int test_duration_enqueue(void) +{ + return !test_stop; +} + +static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); + +static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); +static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); + +static unsigned int nr_enqueuers; +static unsigned int nr_dequeuers; + +struct test { + struct cds_lfcq_node list; + struct rcu_head rcu; +}; + +static struct cds_lfcq_head __attribute__((aligned(CAA_CACHE_LINE_SIZE))) head; +static struct cds_lfcq_tail __attribute__((aligned(CAA_CACHE_LINE_SIZE))) tail; + +static void *thr_enqueuer(void *_count) +{ + unsigned long long *count = _count; + + printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", + "enqueuer", pthread_self(), (unsigned long)gettid()); + + set_affinity(); + + rcu_register_thread(); + + while (!test_go) + { + } + cmm_smp_mb(); + + for (;;) { + struct test *node = malloc(sizeof(*node)); + if (!node) + goto fail; + cds_lfcq_node_init(&node->list); + rcu_read_lock(); + __cds_lfcq_enqueue(&head, &tail, &node->list); + rcu_read_unlock(); + URCU_TLS(nr_successful_enqueues)++; + + if (caa_unlikely(wdelay)) + loop_sleep(wdelay); +fail: + URCU_TLS(nr_enqueues)++; + if (caa_unlikely(!test_duration_enqueue())) + break; + } + + rcu_unregister_thread(); + + count[0] = URCU_TLS(nr_enqueues); + count[1] = URCU_TLS(nr_successful_enqueues); + printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " + "enqueues %llu successful_enqueues %llu\n", + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); + return ((void*)1); + +} + +static void free_node_cb(struct rcu_head *head) +{ + struct test *node = + caa_container_of(head, struct test, rcu); + free(node); +} + +static void *thr_dequeuer(void *_count) +{ + unsigned long long *count = _count; + + printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", + "dequeuer", pthread_self(), (unsigned long)gettid()); + + set_affinity(); + + rcu_register_thread(); + + while (!test_go) + { + } + cmm_smp_mb(); + + for (;;) { + struct cds_lfcq_node *qnode; + + rcu_read_lock(); + qnode = __cds_lfcq_dequeue(&head, &tail); + rcu_read_unlock(); + + if (qnode) { + struct test *node; + + node = caa_container_of(qnode, struct test, list); + call_rcu(&node->rcu, free_node_cb); + URCU_TLS(nr_successful_dequeues)++; + } + + URCU_TLS(nr_dequeues)++; + if (caa_unlikely(!test_duration_dequeue())) + break; + if (caa_unlikely(rduration)) + loop_sleep(rduration); + } + + rcu_unregister_thread(); + printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " + "dequeues %llu, successful_dequeues %llu\n", + pthread_self(), (unsigned long)gettid(), + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + count[0] = URCU_TLS(nr_dequeues); + count[1] = URCU_TLS(nr_successful_dequeues); + return ((void*)2); +} + +static void test_end(unsigned long long *nr_dequeues) +{ + struct cds_lfcq_node *snode; + int ret; + + do { + snode = __cds_lfcq_dequeue(&head, &tail); + if (snode) { + struct test *node; + + node = caa_container_of(snode, struct test, list); + free(node); /* no more concurrent access */ + (*nr_dequeues)++; + } + } while (snode); + + ret = cds_lfcq_finalize(&head, &tail); + assert(!ret); +} + +static void show_usage(int argc, char **argv) +{ + printf("Usage : %s nr_dequeuers nr_enqueuers duration (s)", argv[0]); + printf(" [-d delay] (enqueuer period (in loops))"); + printf(" [-c duration] (dequeuer period (in loops))"); + printf(" [-v] (verbose output)"); + printf(" [-a cpu#] [-a cpu#]... (affinity)"); + printf("\n"); +} + +int main(int argc, char **argv) +{ + int err; + pthread_t *tid_enqueuer, *tid_dequeuer; + void *tret; + unsigned long long *count_enqueuer, *count_dequeuer; + unsigned long long tot_enqueues = 0, tot_dequeues = 0; + unsigned long long tot_successful_enqueues = 0, + tot_successful_dequeues = 0; + unsigned long long end_dequeues = 0; + int i, a, mainret = 0; + + if (argc < 4) { + show_usage(argc, argv); + return -1; + } + + err = sscanf(argv[1], "%u", &nr_dequeuers); + if (err != 1) { + show_usage(argc, argv); + return -1; + } + + err = sscanf(argv[2], "%u", &nr_enqueuers); + if (err != 1) { + show_usage(argc, argv); + return -1; + } + + err = sscanf(argv[3], "%lu", &duration); + if (err != 1) { + show_usage(argc, argv); + return -1; + } + + for (i = 4; i < argc; i++) { + if (argv[i][0] != '-') + continue; + switch (argv[i][1]) { + case 'a': + if (argc < i + 2) { + show_usage(argc, argv); + return -1; + } + a = atoi(argv[++i]); + cpu_affinities[next_aff++] = a; + use_affinity = 1; + printf_verbose("Adding CPU %d affinity\n", a); + break; + case 'c': + if (argc < i + 2) { + show_usage(argc, argv); + return -1; + } + rduration = atol(argv[++i]); + break; + case 'd': + if (argc < i + 2) { + show_usage(argc, argv); + return -1; + } + wdelay = atol(argv[++i]); + break; + case 'v': + verbose_mode = 1; + break; + } + } + + printf_verbose("running test for %lu seconds, %u enqueuers, " + "%u dequeuers.\n", + duration, nr_enqueuers, nr_dequeuers); + printf_verbose("Writer delay : %lu loops.\n", rduration); + printf_verbose("Reader duration : %lu loops.\n", wdelay); + printf_verbose("thread %-6s, thread id : %lx, tid %lu\n", + "main", pthread_self(), (unsigned long)gettid()); + + tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); + tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); + count_enqueuer = malloc(2 * sizeof(*count_enqueuer) * nr_enqueuers); + count_dequeuer = malloc(2 * sizeof(*count_dequeuer) * nr_dequeuers); + cds_lfcq_init(&head, &tail); + err = create_all_cpu_call_rcu_data(0); + if (err) { + printf("Per-CPU call_rcu() worker threads unavailable. Using default global worker thread.\n"); + } + + next_aff = 0; + + for (i = 0; i < nr_enqueuers; i++) { + err = pthread_create(&tid_enqueuer[i], NULL, thr_enqueuer, + &count_enqueuer[2 * i]); + if (err != 0) + exit(1); + } + for (i = 0; i < nr_dequeuers; i++) { + err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, + &count_dequeuer[2 * i]); + if (err != 0) + exit(1); + } + + cmm_smp_mb(); + + test_go = 1; + + for (i = 0; i < duration; i++) { + sleep(1); + if (verbose_mode) + write (1, ".", 1); + } + + test_stop = 1; + + for (i = 0; i < nr_enqueuers; i++) { + err = pthread_join(tid_enqueuer[i], &tret); + if (err != 0) + exit(1); + tot_enqueues += count_enqueuer[2 * i]; + tot_successful_enqueues += count_enqueuer[2 * i + 1]; + } + for (i = 0; i < nr_dequeuers; i++) { + err = pthread_join(tid_dequeuer[i], &tret); + if (err != 0) + exit(1); + tot_dequeues += count_dequeuer[2 * i]; + tot_successful_dequeues += count_dequeuer[2 * i + 1]; + } + + test_end(&end_dequeues); + + printf_verbose("total number of enqueues : %llu, dequeues %llu\n", + tot_enqueues, tot_dequeues); + printf_verbose("total number of successful enqueues : %llu, " + "successful dequeues %llu\n", + tot_successful_enqueues, tot_successful_dequeues); + printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " + "nr_dequeuers %3u " + "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " + "successful enqueues %12llu successful dequeues %12llu " + "end_dequeues %llu nr_ops %12llu\n", + argv[0], duration, nr_enqueuers, wdelay, + nr_dequeuers, rduration, tot_enqueues, tot_dequeues, + tot_successful_enqueues, + tot_successful_dequeues, end_dequeues, + tot_enqueues + tot_dequeues); + if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { + printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " + "succ. dequeues + end dequeues %llu.\n", + tot_successful_enqueues, + tot_successful_dequeues + end_dequeues); + mainret = 1; + } + + free_all_cpu_call_rcu_data(); + free(count_enqueuer); + free(count_dequeuer); + free(tid_enqueuer); + free(tid_dequeuer); + if (!mainret) + exit(EXIT_SUCCESS); + else + exit(EXIT_FAILURE); +} diff --git a/urcu/cds.h b/urcu/cds.h index 78534bb..3976089 100644 --- a/urcu/cds.h +++ b/urcu/cds.h @@ -34,5 +34,6 @@ #include #include #include +#include #endif /* _URCU_CDS_H */ diff --git a/urcu/rculfcqueue.h b/urcu/rculfcqueue.h new file mode 100644 index 0000000..1eff75f --- /dev/null +++ b/urcu/rculfcqueue.h @@ -0,0 +1,139 @@ +#ifndef _URCU_RCULFCQUEUE_H +#define _URCU_RCULFCQUEUE_H + +/* + * urcu/rculfcqueue.h + * + * Userspace RCU library - Lock-Free RCU Concurrent Queue + * + * Copyright 2010-2012 - Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct cds_lfcq_node { + struct cds_lfcq_node *next; + int dummy; +}; + + +struct cds_lfcq_head { + struct cds_lfcq_node *p; + void (*queue_call_rcu)(struct rcu_head *head, + void (*func)(struct rcu_head *head)); +}; + +struct cds_lfcq_tail { + struct cds_lfcq_node *p; +}; + +#ifdef _LGPL_SOURCE + +#include + +#define cds_lfcq_node_init _cds_lfcq_node_init +#define _cds_lfcq_init __cds_lfcq_init +#define cds_lfcq_finalize _cds_lfcq_finalize +#define __cds_lfcq_empty ___cds_lfcq_empty +#define __cds_lfcq_enqueue ___cds_lfcq_enqueue +#define __cds_lfcq_dequeue ___cds_lfcq_dequeue + +#else /* !_LGPL_SOURCE */ + +/* + * cds_lfcq_node_init: initialize lock-free queue node. + * @node: node to initialize. + */ +extern void cds_lfcq_node_init(struct cds_lfcq_node *node); + +/* + * _cds_lfcq_init: intialize lock-free queue. + * @head: head of the queue. + * @tail: tail of the queue. + * queue_call_rcu: call_rcu function to use. + */ +extern void _cds_lfcq_init(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail, + void queue_call_rcu(struct rcu_head *head, + void (*func)(struct rcu_head *head))); + +/* + * cds_lfcq_finalize: finalize lock-free queue. + * + * The queue should be emptied before calling finalize. No concurrent + * enqueue/dequeue should be running when calling finalize. + * + * Return 0 on success, -EPERM if queue is not empty. + */ +extern int cds_lfcq_finalize(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail); + +/* + * cds_lfcq_empty: return whether lock-free queue is empty. + * @head: head of the queue. + * @tail: tail of the queue. + * + * Should be called under rcu read lock critical section. + */ +extern bool __cds_lfcq_empty(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail); + +/* + * __cds_lfcq_enqueue: enqueue a node into lock-free queue. + * + * Should be called under rcu read lock critical section. + */ +extern void __cds_lfcq_enqueue(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail, + struct cds_lfcq_node *node); + +/* + * __cds_lfcq_dequeue: dequeue a node from lock-free queue. + * + * The caller must wait for a grace period to pass before freeing the + * returned node or modifying the cds_lfq_node_rcu structure. + * Returns NULL if queue is empty. + * Should be called under rcu read lock critical section. + */ +extern +struct cds_lfcq_node *__cds_lfcq_dequeue(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail); + +#endif /* !_LGPL_SOURCE */ + +/* + * cds_lfcq_init: intialize lock-free queue with RCU flavor call_rcu. + * @head: head of the queue. + * @tail: tail of the queue. + */ +static inline void cds_lfcq_init(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail) +{ + _cds_lfcq_init(head, tail, call_rcu); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _URCU_RCULFCQUEUE_H */ diff --git a/urcu/static/rculfcqueue.h b/urcu/static/rculfcqueue.h new file mode 100644 index 0000000..d0354f4 --- /dev/null +++ b/urcu/static/rculfcqueue.h @@ -0,0 +1,319 @@ +#ifndef _URCU_STATIC_RCULFCQUEUE_H +#define _URCU_STATIC_RCULFCQUEUE_H + +/* + * urcu/static/rculfcqueue.h + * + * Userspace RCU library - Lock-Free RCU Concurrent Queue + * + * Copyright 2010-2012 - Mathieu Desnoyers + * + * TO BE INCLUDED ONLY IN LGPL-COMPATIBLE CODE. See urcu/rculfcqueue.h + * for linking dynamically with the userspace rcu library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Lock-free RCU queue. Enqueue and dequeue operations hold a RCU read + * lock to deal with cmpxchg ABA problem and guarantee existance of + * nodes being read and modified. This queue is *not* circular: + * head points to the oldest node, tail points to the newest node. + * Keeping a separate head and tail helps with large queues: enqueue and + * dequeue can proceed concurrently without wrestling for exclusive + * access to the same cache-line. + * + * Dequeue retry if it detects that it would be dequeueing the last node + * (it means a dummy node dequeue-requeue is in progress). This ensures + * that there is always at least one node in the queue. + * + * In the dequeue operation, we internally reallocate the dummy node + * upon dequeue/requeue and use call_rcu to free the old one after a + * grace period. + */ + +struct cds_lfcq_node_dummy { + struct cds_lfcq_node parent; + struct rcu_head rcu_head; + struct cds_lfcq_head *head; + struct cds_lfcq_tail *tail; +}; + +static inline +struct cds_lfcq_node *___cds_lfcq_make_dummy(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail, + struct cds_lfcq_node *next) +{ + struct cds_lfcq_node_dummy *dummy; + + dummy = malloc(sizeof(struct cds_lfcq_node_dummy)); + assert(dummy); + dummy->parent.next = next; + dummy->parent.dummy = 1; + dummy->head = head; + dummy->tail = tail; + return &dummy->parent; +} + +static inline +void ___cds_lfcq_free_dummy_cb(struct rcu_head *head) +{ + struct cds_lfcq_node_dummy *dummy; + + dummy = caa_container_of(head, struct cds_lfcq_node_dummy, rcu_head); + free(dummy); +} + +static inline +void ___cds_lfcq_rcu_free_dummy(struct cds_lfcq_node *node) +{ + struct cds_lfcq_node_dummy *dummy; + + assert(node->dummy); + dummy = caa_container_of(node, struct cds_lfcq_node_dummy, parent); + dummy->head->queue_call_rcu(&dummy->rcu_head, ___cds_lfcq_free_dummy_cb); +} + +static inline +void ___cds_lfcq_free_dummy(struct cds_lfcq_node *node) +{ + struct cds_lfcq_node_dummy *dummy; + + assert(node->dummy); + dummy = caa_container_of(node, struct cds_lfcq_node_dummy, parent); + free(dummy); +} + +/* + * cds_lfcq_node_init: initialize lock-free queue node. + * @node: node to initialize. + */ +static inline +void _cds_lfcq_node_init(struct cds_lfcq_node *node) +{ + node->next = NULL; + node->dummy = 0; +} + +/* + * _cds_lfcq_init: intialize lock-free queue. + * @head: head of the queue. + * @tail: tail of the queue. + * queue_call_rcu: call_rcu function to use. + */ +static inline +void __cds_lfcq_init(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail, + void queue_call_rcu(struct rcu_head *head, + void (*func)(struct rcu_head *head))) +{ + /* Set queue head and tail */ + tail->p = ___cds_lfcq_make_dummy(head, tail, NULL); + head->p = tail->p; + head->queue_call_rcu = queue_call_rcu; +} + +static inline +bool ___cds_lfcq_head_empty(struct cds_lfcq_node *node, + struct cds_lfcq_node *next) +{ + return node->dummy && next == NULL; +} + +/* + * __cds_lfcq_empty: return whether lock-free queue is empty. + * @head: head of the queue. + * @tail: tail of the queue. + * + * Should be called under rcu read lock critical section. + */ +static inline +bool ___cds_lfcq_empty(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail) +{ + struct cds_lfcq_node *node, *next; + + for (;;) { + node = rcu_dereference(head->p); + next = rcu_dereference(node->next); + if (next == NULL) + return 1; /* empty */ + /* non-null next, not dummy: not empty. */ + if (!node->dummy) + return 0; /* non-empty */ + + /* + * If first node is a dummy node, but it's not end of + * queue, we need to dequeue it before being able to + * state that the queue is empty. This is required + * because "finalize" expects an empty queue to have + * only one dummy node. It is possible that a queue have + * more than one dummy node if multiple concurrent + * dequeue enqueue dummy nodes simultaneously. + */ + if (uatomic_cmpxchg(&head->p, node, next) != node) + continue; /* Concurrently pushed. */ + /* Free dummy after grace period. */ + ___cds_lfcq_rcu_free_dummy(node); + continue; /* try again */ + } +} + +/* + * cds_lfcq_finalize: finalize lock-free queue. + * + * The queue should be emptied before calling finalize. No concurrent + * enqueue/dequeue should be running when calling finalize. + * + * Return 0 on success, -EPERM if queue is not empty. + */ +static inline +int _cds_lfcq_finalize(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail) +{ + struct cds_lfcq_node *node, *next; + + node = head->p; + next = node->next; + if (!___cds_lfcq_head_empty(node, next)) + return -EPERM; /* not empty */ + ___cds_lfcq_free_dummy(node); + return 0; +} + +/* + * Should be called under rcu read lock critical section. + */ +static inline +void ___cds_lfcq_append(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail, + struct cds_lfcq_node *new_head, + struct cds_lfcq_node *new_tail) +{ + /* + * uatomic_cmpxchg() implicit memory barrier orders earlier stores to + * node before publication. + */ + + for (;;) { + struct cds_lfcq_node *tail_node, *next; + + tail_node = rcu_dereference(tail->p); + /* + * RCU existance guarantee ensures we don't touch + * &tail->next after it has been dequeued and freed. + */ + next = uatomic_cmpxchg(&tail_node->next, NULL, new_head); + if (next == NULL) { + /* + * Tail was at the end of queue, we successfully + * appended to it. Now move tail (another + * enqueue or dequeue might beat us to it, + * that's fine). + */ + (void) uatomic_cmpxchg(&tail->p, tail_node, new_tail); + return; + } else { + /* + * Failure to append to current tail. + * Help moving tail further and retry. + */ + (void) uatomic_cmpxchg(&tail->p, tail_node, next); + continue; + } + } +} + +/* + * __cds_lfcq_enqueue: enqueue a node into lock-free queue. + * + * Should be called under rcu read lock critical section. + */ +static inline +void ___cds_lfcq_enqueue(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail, + struct cds_lfcq_node *node) +{ + ___cds_lfcq_append(head, tail, node, node); +} + +static inline +void ___cds_lfcq_enqueue_dummy(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail) +{ + struct cds_lfcq_node *node; + + node = ___cds_lfcq_make_dummy(head, tail, NULL); + ___cds_lfcq_enqueue(head, tail, node); +} + +/* + * __cds_lfcq_dequeue: dequeue a node from lock-free queue. + * + * The caller must wait for a grace period to pass before freeing the + * returned node or modifying the cds_lfq_node_rcu structure. + * Returns NULL if queue is empty. + * Should be called under rcu read lock critical section. + */ +static inline +struct cds_lfcq_node *___cds_lfcq_dequeue(struct cds_lfcq_head *head, + struct cds_lfcq_tail *tail) +{ + for (;;) { + struct cds_lfcq_node *node, *next; + + /* First node */ + node = rcu_dereference(head->p); + next = rcu_dereference(node->next); + if (___cds_lfcq_head_empty(node, next)) + return NULL; /* empty */ + /* + * We never, ever allow dequeue to get to a state where + * the queue is empty (we need at least one node in the + * queue). This is ensured by checking if the head next + * is NULL, which means we need to enqueue a dummy node + * before we can hope dequeuing anything. + */ + if (!next) { + ___cds_lfcq_enqueue_dummy(head, tail); + next = rcu_dereference(node->next); + } + if (uatomic_cmpxchg(&head->p, node, next) != node) + continue; /* Concurrently pushed. */ + if (node->dummy) { + /* Free dummy after grace period. */ + ___cds_lfcq_rcu_free_dummy(node); + continue; /* try again */ + } + return node; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* _URCU_STATIC_RCULFCQUEUE_H */ -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Mon Nov 5 10:17:21 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 5 Nov 2012 10:17:21 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Fix: Conditionnally disable tests requiring shared libs support Message-ID: <1352128641-26335-1-git-send-email-christian.babeux@efficios.com> When building lttng-ust with shared library support explicitly disabled (e.g.: ./configure --disable-shared), libtool fail with a fatal error: CC tp.lo CC tp2.lo CCLD liblttng-ust-provider-ust-tests-demo.la libtool: link: can not build a shared library libtool: link: See the libtool documentation for more information. libtool: link: Fatal configuration error. The build should not fail because some tests require explicit shared library support, instead they should be skipped. This patch detect that the --disable-shared flag was passed to the configure script and toggle the "NO_SHARED" Automake variable. Thus, the tests that require explicit shared library support can be skipped when the NO_SHARED variable is true. Signed-off-by: Christian Babeux --- configure.ac | 2 ++ tests/demo/Makefile.am | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/configure.ac b/configure.ac index 91ad8d9..87e89d5 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,8 @@ AS_IF([test "x$libtool_fixup" = "xyes"], ]) ]) +AM_CONDITIONAL([NO_SHARED], [test x$enable_shared = xno]) + # Checks for programs. AC_PROG_CC AC_PROG_CXX diff --git a/tests/demo/Makefile.am b/tests/demo/Makefile.am index 0e43255..76ab598 100644 --- a/tests/demo/Makefile.am +++ b/tests/demo/Makefile.am @@ -6,6 +6,10 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -Wsystem-headers # libraries. LIBS = +if NO_SHARED +# Do not build this test if shared libraries support was +# explicitly disabled. +else # Force the shared flag on the noinst libraries since they are # only built static by default FORCE_SHARED_LIB_OPTIONS = -module -shared -avoid-version \ @@ -41,3 +45,4 @@ if LTTNG_UST_BUILD_WITH_LIBC_DL demo_LDADD = -lc endif +endif -- 1.8.0 From mathieu.desnoyers at efficios.com Mon Nov 5 10:40:13 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 5 Nov 2012 10:40:13 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Fix: Conditionnally disable tests requiring shared libs support In-Reply-To: <1352128641-26335-1-git-send-email-christian.babeux@efficios.com> References: <1352128641-26335-1-git-send-email-christian.babeux@efficios.com> Message-ID: <20121105154013.GB7884@Krystal> * Christian Babeux (christian.babeux at efficios.com) wrote: > When building lttng-ust with shared library support explicitly > disabled (e.g.: ./configure --disable-shared), libtool fail with > a fatal error: > > CC tp.lo > CC tp2.lo > CCLD liblttng-ust-provider-ust-tests-demo.la > libtool: link: can not build a shared library > libtool: link: See the libtool documentation for more information. > libtool: link: Fatal configuration error. > > The build should not fail because some tests require explicit shared > library support, instead they should be skipped. > > This patch detect that the --disable-shared flag was passed to the > configure script and toggle the "NO_SHARED" Automake variable. > Thus, the tests that require explicit shared library support can > be skipped when the NO_SHARED variable is true. merged into master and stable-2.0, thanks! Mathieu > > Signed-off-by: Christian Babeux > --- > configure.ac | 2 ++ > tests/demo/Makefile.am | 5 +++++ > 2 files changed, 7 insertions(+) > > diff --git a/configure.ac b/configure.ac > index 91ad8d9..87e89d5 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -64,6 +64,8 @@ AS_IF([test "x$libtool_fixup" = "xyes"], > ]) > ]) > > +AM_CONDITIONAL([NO_SHARED], [test x$enable_shared = xno]) > + > # Checks for programs. > AC_PROG_CC > AC_PROG_CXX > diff --git a/tests/demo/Makefile.am b/tests/demo/Makefile.am > index 0e43255..76ab598 100644 > --- a/tests/demo/Makefile.am > +++ b/tests/demo/Makefile.am > @@ -6,6 +6,10 @@ AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include -Wsystem-headers > # libraries. > LIBS = > > +if NO_SHARED > +# Do not build this test if shared libraries support was > +# explicitly disabled. > +else > # Force the shared flag on the noinst libraries since they are > # only built static by default > FORCE_SHARED_LIB_OPTIONS = -module -shared -avoid-version \ > @@ -41,3 +45,4 @@ if LTTNG_UST_BUILD_WITH_LIBC_DL > demo_LDADD = -lc > endif > > +endif > -- > 1.8.0 > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Mon Nov 5 12:33:57 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 5 Nov 2012 12:33:57 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Add return code to the testpoint mechanism Message-ID: <1352136837-20694-1-git-send-email-christian.babeux@efficios.com> The testpoint processing could fail and currently there is no mechanism to notify the caller of such failures. This patch add an int return code to the testpoint prototype. Non-zero return code indicate failure. When using the testpoint mechanism, the caller should properly handle testpoint failure cases and trigger the appropriate response (error handling, thread teardown, etc.). Signed-off-by: Christian Babeux --- src/bin/lttng-sessiond/main.c | 36 ++++++++++++++++++++++++++---------- src/common/testpoint/testpoint.h | 20 ++++++++++---------- tests/tools/health/health_exit.c | 20 +++++++++++++++----- tests/tools/health/health_stall.c | 12 +++++++++--- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index cedd356..3d74b66 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -690,11 +690,15 @@ static void *thread_manage_kernel(void *data) DBG("Thread manage kernel started"); - testpoint(thread_manage_kernel); + if (testpoint(thread_manage_kernel)) { + goto error; + } health_code_update(&health_thread_kernel); - testpoint(thread_manage_kernel_before_loop); + if (testpoint(thread_manage_kernel_before_loop)) { + goto error; + } ret = create_thread_poll_set(&events, 2); if (ret < 0) { @@ -886,7 +890,9 @@ static void *thread_manage_consumer(void *data) restart: health_poll_update(&consumer_data->health); - testpoint(thread_manage_consumer); + if (testpoint(thread_manage_consumer)) { + goto error; + } ret = lttng_poll_wait(&events, -1); health_poll_update(&consumer_data->health); @@ -1085,11 +1091,13 @@ static void *thread_manage_apps(void *data) DBG("[thread] Manage application started"); - testpoint(thread_manage_apps); - rcu_register_thread(); rcu_thread_online(); + if (testpoint(thread_manage_apps)) { + goto error; + } + health_code_update(&health_thread_app_manage); ret = create_thread_poll_set(&events, 2); @@ -1102,7 +1110,9 @@ static void *thread_manage_apps(void *data) goto error; } - testpoint(thread_manage_apps_before_loop); + if (testpoint(thread_manage_apps_before_loop)) { + goto error; + } health_code_update(&health_thread_app_manage); @@ -1327,7 +1337,9 @@ static void *thread_registration_apps(void *data) DBG("[thread] Manage application registration started"); - testpoint(thread_registration_apps); + if (testpoint(thread_registration_apps)) { + goto error; + } ret = lttcomm_listen_unix_sock(apps_sock); if (ret < 0) { @@ -3054,10 +3066,12 @@ static void *thread_manage_clients(void *data) DBG("[thread] Manage client started"); - testpoint(thread_manage_clients); - rcu_register_thread(); + if (testpoint(thread_manage_clients)) { + goto error; + } + health_code_update(&health_thread_cmd); ret = lttcomm_listen_unix_sock(client_sock); @@ -3087,7 +3101,9 @@ static void *thread_manage_clients(void *data) kill(ppid, SIGUSR1); } - testpoint(thread_manage_clients_before_loop); + if (testpoint(thread_manage_clients_before_loop)) { + goto error; + } health_code_update(&health_thread_cmd); diff --git a/src/common/testpoint/testpoint.h b/src/common/testpoint/testpoint.h index ba3af8a..8d5d9db 100644 --- a/src/common/testpoint/testpoint.h +++ b/src/common/testpoint/testpoint.h @@ -32,37 +32,37 @@ void *lttng_testpoint_lookup(const char *name); * Testpoint is only active if the global lttng_testpoint_activated flag is * set. */ -#define testpoint(name) \ - do { \ - if (caa_unlikely(lttng_testpoint_activated)) { \ - __testpoint_##name##_wrapper(); \ - } \ - } while (0) +#define testpoint(name) \ + ((caa_unlikely(lttng_testpoint_activated)) \ + ? __testpoint_##name##_wrapper() : 0) /* * One wrapper per testpoint is generated. This is to keep track of the symbol * lookup status and the corresponding function pointer, if any. + * Return a non-zero error code to indicate failure. */ #define _TESTPOINT_DECL(_name) \ - static inline void __testpoint_##_name##_wrapper(void) \ + static inline int __testpoint_##_name##_wrapper(void) \ { \ - static void (*tp)(void); \ + int ret = 0; \ + static int (*tp)(void); \ static int found; \ const char *tp_name = "__testpoint_" #_name; \ \ if (tp) { \ - tp(); \ + ret = tp(); \ } else { \ if (!found) { \ tp = lttng_testpoint_lookup(tp_name); \ if (tp) { \ found = 1; \ - tp(); \ + ret = tp(); \ } else { \ found = -1; \ } \ } \ } \ + return ret; \ } /* Testpoint declaration */ diff --git a/tests/tools/health/health_exit.c b/tests/tools/health/health_exit.c index 258b08d..8e41405 100644 --- a/tests/tools/health/health_exit.c +++ b/tests/tools/health/health_exit.c @@ -35,47 +35,57 @@ int check_env_var(const char *env) return 0; } -void __testpoint_thread_manage_clients(void) +int __testpoint_thread_manage_clients(void) { const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_EXIT"; if (check_env_var(var)) { pthread_exit(NULL); } + + return 0; } -void __testpoint_thread_registration_apps(void) +int __testpoint_thread_registration_apps(void) { const char *var = "LTTNG_THREAD_REG_APPS_EXIT"; if (check_env_var(var)) { pthread_exit(NULL); } + + return 0; } -void __testpoint_thread_manage_apps(void) +int __testpoint_thread_manage_apps(void) { const char *var = "LTTNG_THREAD_MANAGE_APPS_EXIT"; if (check_env_var(var)) { pthread_exit(NULL); } + + return 0; } -void __testpoint_thread_manage_kernel(void) +int __testpoint_thread_manage_kernel(void) { const char *var = "LTTNG_THREAD_MANAGE_KERNEL_EXIT"; if (check_env_var(var)) { pthread_exit(NULL); } + + return 0; } -void __testpoint_thread_manage_consumer(void) +int __testpoint_thread_manage_consumer(void) { const char *var = "LTTNG_THREAD_MANAGE_CONSUMER_EXIT"; if (check_env_var(var)) { pthread_exit(NULL); } + + return 0; } diff --git a/tests/tools/health/health_stall.c b/tests/tools/health/health_stall.c index f91bd49..6dddc2e 100644 --- a/tests/tools/health/health_stall.c +++ b/tests/tools/health/health_stall.c @@ -38,29 +38,35 @@ int check_env_var(const char *env) return 0; } -void __testpoint_thread_manage_clients_before_loop(void) +int __testpoint_thread_manage_clients_before_loop(void) { const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_STALL"; if (check_env_var(var)) { sleep(STALL_TIME); } + + return 0; } -void __testpoint_thread_manage_kernel_before_loop(void) +int __testpoint_thread_manage_kernel_before_loop(void) { const char *var = "LTTNG_THREAD_MANAGE_KERNEL_STALL"; if (check_env_var(var)) { sleep(STALL_TIME); } + + return 0; } -void __testpoint_thread_manage_apps_before_loop(void) +int __testpoint_thread_manage_apps_before_loop(void) { const char *var = "LTTNG_THREAD_MANAGE_APPS_STALL"; if (check_env_var(var)) { sleep(STALL_TIME); } + + return 0; } -- 1.8.0 From mathieu.desnoyers at efficios.com Mon Nov 5 15:01:26 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 5 Nov 2012 15:01:26 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Add return code to the testpoint mechanism In-Reply-To: <1352136837-20694-1-git-send-email-christian.babeux@efficios.com> References: <1352136837-20694-1-git-send-email-christian.babeux@efficios.com> Message-ID: <20121105200126.GA11945@Krystal> * Christian Babeux (christian.babeux at efficios.com) wrote: > The testpoint processing could fail and currently there is no > mechanism to notify the caller of such failures. This patch add an add -> adds > int return code to the testpoint prototype. Non-zero return code > indicate failure. > > When using the testpoint mechanism, the caller should properly handle > testpoint failure cases and trigger the appropriate response > (error handling, thread teardown, etc.). > > Signed-off-by: Christian Babeux > --- > src/bin/lttng-sessiond/main.c | 36 ++++++++++++++++++++++++++---------- > src/common/testpoint/testpoint.h | 20 ++++++++++---------- > tests/tools/health/health_exit.c | 20 +++++++++++++++----- > tests/tools/health/health_stall.c | 12 +++++++++--- > 4 files changed, 60 insertions(+), 28 deletions(-) > > diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c > index cedd356..3d74b66 100644 > --- a/src/bin/lttng-sessiond/main.c > +++ b/src/bin/lttng-sessiond/main.c > @@ -690,11 +690,15 @@ static void *thread_manage_kernel(void *data) > > DBG("Thread manage kernel started"); > > - testpoint(thread_manage_kernel); > + if (testpoint(thread_manage_kernel)) { > + goto error; > + } Blindly goto error is bogus: the error flag executes some teardown of variables that are not yet initialized. This error appears multiple times in this patch. > > health_code_update(&health_thread_kernel); > > - testpoint(thread_manage_kernel_before_loop); > + if (testpoint(thread_manage_kernel_before_loop)) { > + goto error; > + } > > ret = create_thread_poll_set(&events, 2); > if (ret < 0) { > @@ -886,7 +890,9 @@ static void *thread_manage_consumer(void *data) > restart: > health_poll_update(&consumer_data->health); > > - testpoint(thread_manage_consumer); > + if (testpoint(thread_manage_consumer)) { > + goto error; > + } > > ret = lttng_poll_wait(&events, -1); > health_poll_update(&consumer_data->health); > @@ -1085,11 +1091,13 @@ static void *thread_manage_apps(void *data) > > DBG("[thread] Manage application started"); > > - testpoint(thread_manage_apps); > - > rcu_register_thread(); > rcu_thread_online(); > > + if (testpoint(thread_manage_apps)) { > + goto error; > + } > + > health_code_update(&health_thread_app_manage); > > ret = create_thread_poll_set(&events, 2); > @@ -1102,7 +1110,9 @@ static void *thread_manage_apps(void *data) > goto error; > } > > - testpoint(thread_manage_apps_before_loop); > + if (testpoint(thread_manage_apps_before_loop)) { > + goto error; > + } > > health_code_update(&health_thread_app_manage); > > @@ -1327,7 +1337,9 @@ static void *thread_registration_apps(void *data) > > DBG("[thread] Manage application registration started"); > > - testpoint(thread_registration_apps); > + if (testpoint(thread_registration_apps)) { > + goto error; > + } > > ret = lttcomm_listen_unix_sock(apps_sock); > if (ret < 0) { > @@ -3054,10 +3066,12 @@ static void *thread_manage_clients(void *data) > > DBG("[thread] Manage client started"); > > - testpoint(thread_manage_clients); > - > rcu_register_thread(); > > + if (testpoint(thread_manage_clients)) { > + goto error; > + } > + > health_code_update(&health_thread_cmd); > > ret = lttcomm_listen_unix_sock(client_sock); > @@ -3087,7 +3101,9 @@ static void *thread_manage_clients(void *data) > kill(ppid, SIGUSR1); > } > > - testpoint(thread_manage_clients_before_loop); > + if (testpoint(thread_manage_clients_before_loop)) { > + goto error; > + } > > health_code_update(&health_thread_cmd); > > diff --git a/src/common/testpoint/testpoint.h b/src/common/testpoint/testpoint.h > index ba3af8a..8d5d9db 100644 > --- a/src/common/testpoint/testpoint.h > +++ b/src/common/testpoint/testpoint.h > @@ -32,37 +32,37 @@ void *lttng_testpoint_lookup(const char *name); > * Testpoint is only active if the global lttng_testpoint_activated flag is > * set. > */ > -#define testpoint(name) \ > - do { \ > - if (caa_unlikely(lttng_testpoint_activated)) { \ > - __testpoint_##name##_wrapper(); \ > - } \ > - } while (0) > +#define testpoint(name) \ > + ((caa_unlikely(lttng_testpoint_activated)) \ > + ? __testpoint_##name##_wrapper() : 0) > > /* > * One wrapper per testpoint is generated. This is to keep track of the symbol > * lookup status and the corresponding function pointer, if any. > + * Return a non-zero error code to indicate failure. This comment should go with the "testpoint()" macro above, not _TESTPOINT_DECL. The testpoint() macro is what users will expect to return something, not _TESTPOINT_DECL. > */ > #define _TESTPOINT_DECL(_name) \ > - static inline void __testpoint_##_name##_wrapper(void) \ > + static inline int __testpoint_##_name##_wrapper(void) \ > { \ > - static void (*tp)(void); \ > + int ret = 0; \ > + static int (*tp)(void); \ > static int found; \ > const char *tp_name = "__testpoint_" #_name; \ > \ > if (tp) { \ > - tp(); \ > + ret = tp(); \ > } else { \ > if (!found) { \ > tp = lttng_testpoint_lookup(tp_name); \ > if (tp) { \ > found = 1; \ > - tp(); \ > + ret = tp(); \ > } else { \ > found = -1; \ > } \ > } \ > } \ > + return ret; \ > } > > /* Testpoint declaration */ > diff --git a/tests/tools/health/health_exit.c b/tests/tools/health/health_exit.c > index 258b08d..8e41405 100644 > --- a/tests/tools/health/health_exit.c > +++ b/tests/tools/health/health_exit.c > @@ -35,47 +35,57 @@ int check_env_var(const char *env) > return 0; > } > > -void __testpoint_thread_manage_clients(void) > +int __testpoint_thread_manage_clients(void) > { > const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_EXIT"; > > if (check_env_var(var)) { > pthread_exit(NULL); > } > + > + return 0; > } > > -void __testpoint_thread_registration_apps(void) > +int __testpoint_thread_registration_apps(void) > { > const char *var = "LTTNG_THREAD_REG_APPS_EXIT"; > > if (check_env_var(var)) { > pthread_exit(NULL); > } > + > + return 0; > } > > -void __testpoint_thread_manage_apps(void) > +int __testpoint_thread_manage_apps(void) > { > const char *var = "LTTNG_THREAD_MANAGE_APPS_EXIT"; > > if (check_env_var(var)) { > pthread_exit(NULL); > } > + > + return 0; > } > > -void __testpoint_thread_manage_kernel(void) > +int __testpoint_thread_manage_kernel(void) > { > const char *var = "LTTNG_THREAD_MANAGE_KERNEL_EXIT"; > > if (check_env_var(var)) { > pthread_exit(NULL); > } > + > + return 0; > } > > -void __testpoint_thread_manage_consumer(void) > +int __testpoint_thread_manage_consumer(void) > { > const char *var = "LTTNG_THREAD_MANAGE_CONSUMER_EXIT"; > > if (check_env_var(var)) { > pthread_exit(NULL); > } > + > + return 0; > } > diff --git a/tests/tools/health/health_stall.c b/tests/tools/health/health_stall.c > index f91bd49..6dddc2e 100644 > --- a/tests/tools/health/health_stall.c > +++ b/tests/tools/health/health_stall.c > @@ -38,29 +38,35 @@ int check_env_var(const char *env) > return 0; > } > > -void __testpoint_thread_manage_clients_before_loop(void) > +int __testpoint_thread_manage_clients_before_loop(void) > { > const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_STALL"; > > if (check_env_var(var)) { > sleep(STALL_TIME); This is not really a problem with this patch, but would be good to fix with another patch: sleep can return the number of seconds left to sleep if interrupted, so it should be used with: unsigned int sleep_time; sleep_time = STALL_TIME; while (sleep_time > 0) { sleep_time = sleep(sleep_time); } Thanks, Mathieu > } > + > + return 0; > } > > -void __testpoint_thread_manage_kernel_before_loop(void) > +int __testpoint_thread_manage_kernel_before_loop(void) > { > const char *var = "LTTNG_THREAD_MANAGE_KERNEL_STALL"; > > if (check_env_var(var)) { > sleep(STALL_TIME); > } > + > + return 0; > } > > -void __testpoint_thread_manage_apps_before_loop(void) > +int __testpoint_thread_manage_apps_before_loop(void) > { > const char *var = "LTTNG_THREAD_MANAGE_APPS_STALL"; > > if (check_env_var(var)) { > sleep(STALL_TIME); > } > + > + return 0; > } > -- > 1.8.0 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Mon Nov 5 16:20:13 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Mon, 5 Nov 2012 16:20:13 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix: Do not install health tests helper libraries Message-ID: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> The libraries libhealthexit and libhealthstall should not be installed on the user system. They are only useful for the health check tests. Signed-off-by: Christian Babeux --- tests/tools/health/Makefile.am | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am index 9fab582..d1d4919 100644 --- a/tests/tools/health/Makefile.am +++ b/tests/tools/health/Makefile.am @@ -10,8 +10,6 @@ endif UTILS= -lib_LTLIBRARIES=libhealthexit.la libhealthstall.la - # Health thread exit ld_preloaded test lib libhealthexit_la_SOURCES=health_exit.c libhealthexit_la_LDFLAGS= -module @@ -21,6 +19,7 @@ libhealthstall_la_SOURCES=health_stall.c libhealthstall_la_LDFLAGS= -module noinst_PROGRAMS = health_check +noinst_LTLIBRARIES = libhealthexit.la libhealthstall.la health_check_SOURCES = health_check.c $(UTILS) health_check_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \ -- 1.8.0 From mathieu.desnoyers at efficios.com Mon Nov 5 17:11:03 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 5 Nov 2012 17:11:03 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix: Do not install health tests helper libraries In-Reply-To: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> References: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> Message-ID: <20121105221103.GB13619@Krystal> * Christian Babeux (christian.babeux at efficios.com) wrote: > The libraries libhealthexit and libhealthstall should not be > installed on the user system. They are only useful for the > health check tests. > > Signed-off-by: Christian Babeux Acked-by: Mathieu Desnoyers > --- > tests/tools/health/Makefile.am | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am > index 9fab582..d1d4919 100644 > --- a/tests/tools/health/Makefile.am > +++ b/tests/tools/health/Makefile.am > @@ -10,8 +10,6 @@ endif > > UTILS= > > -lib_LTLIBRARIES=libhealthexit.la libhealthstall.la > - > # Health thread exit ld_preloaded test lib > libhealthexit_la_SOURCES=health_exit.c > libhealthexit_la_LDFLAGS= -module > @@ -21,6 +19,7 @@ libhealthstall_la_SOURCES=health_stall.c > libhealthstall_la_LDFLAGS= -module > > noinst_PROGRAMS = health_check > +noinst_LTLIBRARIES = libhealthexit.la libhealthstall.la > > health_check_SOURCES = health_check.c $(UTILS) > health_check_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \ > -- > 1.8.0 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Tue Nov 6 13:32:05 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Tue, 6 Nov 2012 13:32:05 -0500 Subject: [lttng-dev] [PATCH v2 lttng-tools] Fix: Do not install health tests helper libraries In-Reply-To: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> References: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> Message-ID: <1352226725-27207-1-git-send-email-christian.babeux@efficios.com> The libraries libhealthexit and libhealthstall should not be installed on the user system. They are only useful for the health check tests. Furthermore, when adding libraries to noinst_LTLIBRARIES, libtool will only build these as static libraries (see [1] for a workaround). This is fine for most use cases, but for the health tests, we _must_ have shared libraries (the nature of the tests require LD_PRELOAD), hence we force the build of a shared object. Forcing shared object has the unfortunate side-effect of breaking builds where configure was invoked with "--disable-shared" flag. Instead of failing badly, detect this flag and skip the health tests altogether. noinst shared libs: [1] - https://lists.gnu.org/archive/html/libtool/2008-06/msg00082.html Signed-off-by: Christian Babeux --- configure.ac | 2 ++ tests/tools/health/Makefile.am | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index 72daf7e..a3120fc 100644 --- a/configure.ac +++ b/configure.ac @@ -39,6 +39,8 @@ AS_IF([test "x$libtool_fixup" = "xyes"], ]) ]) +AM_CONDITIONAL([NO_SHARED], [test x$enable_shared = xno]) + AC_CHECK_HEADERS([ \ sys/types.h unistd.h fcntl.h string.h pthread.h limits.h \ signal.h stdlib.h sys/un.h sys/socket.h stdlib.h stdio.h \ diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am index 9fab582..f1a5d91 100644 --- a/tests/tools/health/Makefile.am +++ b/tests/tools/health/Makefile.am @@ -8,23 +8,27 @@ if LTTNG_TOOLS_BUILD_WITH_LIBC_DL AM_LDFLAGS += -lc endif -UTILS= - -lib_LTLIBRARIES=libhealthexit.la libhealthstall.la +if NO_SHARED +# Do not build this test if shared libraries support was +# explicitly disabled. +else +# In order to test the health check feature, the libhealth* libs +# must be built as .so to be able to LD_PRELOAD them. +FORCE_SHARED_LIB_OPTIONS = -module -shared -avoid-version \ + -rpath $(abs_builddir) # Health thread exit ld_preloaded test lib libhealthexit_la_SOURCES=health_exit.c -libhealthexit_la_LDFLAGS= -module +libhealthexit_la_LDFLAGS= $(FORCE_SHARED_LIB_OPTIONS) # Health thread stall ld_preloaded test lib libhealthstall_la_SOURCES=health_stall.c -libhealthstall_la_LDFLAGS= -module +libhealthstall_la_LDFLAGS= $(FORCE_SHARED_LIB_OPTIONS) noinst_PROGRAMS = health_check +noinst_LTLIBRARIES = libhealthexit.la libhealthstall.la health_check_SOURCES = health_check.c $(UTILS) health_check_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \ $(top_builddir)/src/common/libcommon.la - -noinst_SCRIPTS = -EXTRA_DIST = +endif -- 1.8.0 From mathieu.desnoyers at efficios.com Tue Nov 6 13:43:22 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 6 Nov 2012 13:43:22 -0500 Subject: [lttng-dev] [PATCH v2 lttng-tools] Fix: Do not install health tests helper libraries In-Reply-To: <1352226725-27207-1-git-send-email-christian.babeux@efficios.com> References: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> <1352226725-27207-1-git-send-email-christian.babeux@efficios.com> Message-ID: <20121106184322.GA8453@Krystal> * Christian Babeux (christian.babeux at efficios.com) wrote: > The libraries libhealthexit and libhealthstall should not be > installed on the user system. They are only useful for the > health check tests. > > Furthermore, when adding libraries to noinst_LTLIBRARIES, > libtool will only build these as static libraries (see [1] for a > workaround). This is fine for most use cases, but for the health > tests, we _must_ have shared libraries (the nature of the tests > require LD_PRELOAD), hence we force the build of a shared object. > > Forcing shared object has the unfortunate side-effect of breaking > builds where configure was invoked with "--disable-shared" flag. > Instead of failing badly, detect this flag and skip the health > tests altogether. > > noinst shared libs: > [1] - https://lists.gnu.org/archive/html/libtool/2008-06/msg00082.html > > Signed-off-by: Christian Babeux Acked-by: Mathieu Desnoyers > --- > configure.ac | 2 ++ > tests/tools/health/Makefile.am | 20 ++++++++++++-------- > 2 files changed, 14 insertions(+), 8 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 72daf7e..a3120fc 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -39,6 +39,8 @@ AS_IF([test "x$libtool_fixup" = "xyes"], > ]) > ]) > > +AM_CONDITIONAL([NO_SHARED], [test x$enable_shared = xno]) > + > AC_CHECK_HEADERS([ \ > sys/types.h unistd.h fcntl.h string.h pthread.h limits.h \ > signal.h stdlib.h sys/un.h sys/socket.h stdlib.h stdio.h \ > diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am > index 9fab582..f1a5d91 100644 > --- a/tests/tools/health/Makefile.am > +++ b/tests/tools/health/Makefile.am > @@ -8,23 +8,27 @@ if LTTNG_TOOLS_BUILD_WITH_LIBC_DL > AM_LDFLAGS += -lc > endif > > -UTILS= > - > -lib_LTLIBRARIES=libhealthexit.la libhealthstall.la > +if NO_SHARED > +# Do not build this test if shared libraries support was > +# explicitly disabled. > +else > +# In order to test the health check feature, the libhealth* libs > +# must be built as .so to be able to LD_PRELOAD them. > +FORCE_SHARED_LIB_OPTIONS = -module -shared -avoid-version \ > + -rpath $(abs_builddir) > > # Health thread exit ld_preloaded test lib > libhealthexit_la_SOURCES=health_exit.c > -libhealthexit_la_LDFLAGS= -module > +libhealthexit_la_LDFLAGS= $(FORCE_SHARED_LIB_OPTIONS) > > # Health thread stall ld_preloaded test lib > libhealthstall_la_SOURCES=health_stall.c > -libhealthstall_la_LDFLAGS= -module > +libhealthstall_la_LDFLAGS= $(FORCE_SHARED_LIB_OPTIONS) > > noinst_PROGRAMS = health_check > +noinst_LTLIBRARIES = libhealthexit.la libhealthstall.la > > health_check_SOURCES = health_check.c $(UTILS) > health_check_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \ > $(top_builddir)/src/common/libcommon.la > - > -noinst_SCRIPTS = > -EXTRA_DIST = > +endif > -- > 1.8.0 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Tue Nov 6 14:56:19 2012 From: dgoulet at efficios.com (David Goulet) Date: Tue, 06 Nov 2012 14:56:19 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix: Do not install health tests helper libraries In-Reply-To: <20121105221103.GB13619@Krystal> References: <1352150413-16685-1-git-send-email-christian.babeux@efficios.com> <20121105221103.GB13619@Krystal> Message-ID: <50996B63.2020602@efficios.com> Merged! Thanks! David Mathieu Desnoyers: > * Christian Babeux (christian.babeux at efficios.com) wrote: >> The libraries libhealthexit and libhealthstall should not be >> installed on the user system. They are only useful for the >> health check tests. >> >> Signed-off-by: Christian Babeux > > Acked-by: Mathieu Desnoyers > >> --- >> tests/tools/health/Makefile.am | 3 +-- >> 1 file changed, 1 insertion(+), 2 deletions(-) >> >> diff --git a/tests/tools/health/Makefile.am b/tests/tools/health/Makefile.am >> index 9fab582..d1d4919 100644 >> --- a/tests/tools/health/Makefile.am >> +++ b/tests/tools/health/Makefile.am >> @@ -10,8 +10,6 @@ endif >> >> UTILS= >> >> -lib_LTLIBRARIES=libhealthexit.la libhealthstall.la >> - >> # Health thread exit ld_preloaded test lib >> libhealthexit_la_SOURCES=health_exit.c >> libhealthexit_la_LDFLAGS= -module >> @@ -21,6 +19,7 @@ libhealthstall_la_SOURCES=health_stall.c >> libhealthstall_la_LDFLAGS= -module >> >> noinst_PROGRAMS = health_check >> +noinst_LTLIBRARIES = libhealthexit.la libhealthstall.la >> >> health_check_SOURCES = health_check.c $(UTILS) >> health_check_LDADD = $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \ >> -- >> 1.8.0 >> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > From christian.babeux at efficios.com Tue Nov 6 17:00:53 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Tue, 6 Nov 2012 17:00:53 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix: Proper teardown of thread_manage_clients on failure of listen/create_poll Message-ID: <1352239253-8665-1-git-send-email-christian.babeux@efficios.com> Currently, if the call to lttcomm_listen_unix_sock or create_thread_poll_set fails, the error handling and thread teardown code path is triggered via a jump to an error label. This error handling path closes the sockets that were used and cleanup the poll set. If the listen fails, the poll set will tentatively be cleaned even though it has never been initialized. This patch add 2 labels to differentiate the error handling paths needed in case of failure of lttcomm_listen_unix_sock or create_thread_poll_set. Signed-off-by: Christian Babeux --- src/bin/lttng-sessiond/main.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index ce2213c..39a2a41 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -3062,7 +3062,7 @@ static void *thread_manage_clients(void *data) ret = lttcomm_listen_unix_sock(client_sock); if (ret < 0) { - goto error; + goto error_listen; } /* @@ -3071,7 +3071,7 @@ static void *thread_manage_clients(void *data) */ ret = create_thread_poll_set(&events, 2); if (ret < 0) { - goto error; + goto error_create_poll; } /* Add the application registration socket */ @@ -3244,13 +3244,6 @@ static void *thread_manage_clients(void *data) exit: error: - if (err) { - health_error(&health_thread_cmd); - ERR("Health error occurred in %s", __func__); - } - health_exit(&health_thread_cmd); - - DBG("Client thread dying"); unlink(client_unix_sock_path); if (client_sock >= 0) { ret = close(client_sock); @@ -3268,6 +3261,16 @@ error: lttng_poll_clean(&events); clean_command_ctx(&cmd_ctx); +error_listen: +error_create_poll: + if (err) { + health_error(&health_thread_cmd); + ERR("Health error occurred in %s", __func__); + } + health_exit(&health_thread_cmd); + + DBG("Client thread dying"); + rcu_unregister_thread(); return NULL; } -- 1.8.0 From david.bryant at quantum.com Wed Nov 7 02:36:32 2012 From: david.bryant at quantum.com (David Bryant) Date: Wed, 7 Nov 2012 18:06:32 +1030 Subject: [lttng-dev] Fix filter: pointer to string, not string, should be on stack -- query Message-ID: <509A0F80.1070308@quantum.com> Hi, I'm trying to understand the following changeset: commit 27f4b6094f399f2fe231b58801dce98cbd21baa9 Author: Mathieu Desnoyers Date: Tue Sep 4 12:17:07 2012 -0400 Fix filter: pointer to string, not string, should be on stack Fixes #329 Signed-off-by: Mathieu Desnoyers Bug link: https://bugs.lttng.org/issues/329 The patch forces the ctf_string() argument to be an lvalue. It appears to be in support of tracepoint filtering of the sort: lttng enable-event ust_tests_demo2:loop -u --filter 'stringfield=="text"' Because the argument must be an lvalue the examples/easy-ust won't compile (anymore) with the following patch: diff -u --recursive easy-ust/sample_component_provider.h easy-ust-reproduce/sample_component_provider.h --- easy-ust/sample_component_provider.h 2012-11-07 17:00:09.879299565 +1030 +++ easy-ust-reproduce/sample_component_provider.h 2012-11-07 16:57:02.121647871 +1030 @@ -61,6 +61,11 @@ */ #include +#ifndef SEE_ONCE +#define SEE_ONCE +static inline char * echo(char * c) { return c; } +#endif + /* * The following tracepoint event writes a message (c string) into the * field message of the trace event message in the provider @@ -100,7 +105,7 @@ * The ctf_string macro takes a c string and writes it into a field * named "message" */ - ctf_string(message, text) + ctf_string(message, echo(text)) ) ) /* Compilation results in: $ make gcc -I/home/dbryant/local5/include -I. -c -o sample.o sample.c gcc -I/home/dbryant/local5/include -I. -c -o tp.o tp.c In file included from /home/dbryant/local5/include/lttng/ust-tracepoint-event.h:338:0, from /home/dbryant/local5/include/lttng/tracepoint-event.h:41, from sample_component_provider.h:140, from tp.c:25: ././sample_component_provider.h: In function ?__event_prepare_filter_stack__sample_component___message?: ././sample_component_provider.h:76:1: error: lvalue required as unary ?&? operand make: *** [tp.o] Error 1 I'm trying to make sense of all this. I've been passing generated-on-the-fly rvalues through ctf_string() using v2.0.5 with no (noticeable) problems. Now I can't. Should I never have been doing that, or has this change had an unintended consequence? Admittedly I haven't been filtering tracepoints on text criteria and am not considering things from that angle. Should ctf_string() arguments always be string literals?! Thanks, Dave ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From dafidbrown at gmail.com Wed Nov 7 04:33:37 2012 From: dafidbrown at gmail.com (David Brown) Date: Wed, 7 Nov 2012 09:33:37 +0000 Subject: [lttng-dev] Offering to help Message-ID: Hello folks, I am interested in some of the problems that the LTTNG tool can be used to address. I have some time available, many years experience in vaguely related areas and am willing to take direction. If my help as a developer, tester, or documenter would be appreciated, please respond. regards, Dave Brown From michel.dagenais at polymtl.ca Wed Nov 7 11:18:29 2012 From: michel.dagenais at polymtl.ca (Michel Dagenais) Date: Wed, 7 Nov 2012 11:18:29 -0500 (EST) Subject: [lttng-dev] Offering to help In-Reply-To: <2066018320.17359391352304986020.JavaMail.root@srv11.zimbra.polymtl.ca> Message-ID: <1697346043.17359581352305109343.JavaMail.root@srv11.zimbra.polymtl.ca> > I am interested in some of the problems that the LTTNG tool can be > used to address. I have some time available, many years experience in > vaguely related areas and am willing to take direction. > > If my help as a developer, tester, or documenter would be appreciated, Your help is indeed most welcome. There are many possible areas for contribution depending on your interests: - documentation/tutorials - more of the automated tests - LTTV would benefit from restructuring work, some is underway but not as actively as would be needed, in C/C++ - There are several views/enhancements that could be added to Eclipse TMF, in java - There are a number of enhancements to the core tracing infrastructure which are planned but not yet implemented (flight recorder mode, init time tracing, filters in kernel mode...) From mathieu.desnoyers at efficios.com Wed Nov 7 12:33:55 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 7 Nov 2012 12:33:55 -0500 Subject: [lttng-dev] Offering to help In-Reply-To: References: Message-ID: <20121107173355.GA28974@Krystal> Hi David! Glad to see you are interested in helping us :) I see you are on oftc #lttng, which is indeed the right first step. We have plently of things to work on in this project in all your areas of expertise. One that come up to my mind, and have been bugging me for a while, is that we lack a sort of "quickstart guide" for lttng 2.x. A new user has only manpages (and --help) to refer to, but there is no comprehensive document that get people up and running quickly. Is this something you would be interested to contribute ? Proposing it on lttng-dev should help you get feedback. Other than that, a second step would be to look at the bug tracker: bugs.lttng.org , especially the "feature requests" and some low priority bugs that are sitting there. If anything catch your interest, it could be a nice way to dig into the project. Thanks! Mathieu * David Brown (dafidbrown at gmail.com) wrote: > Hello folks, > > I am interested in some of the problems that the LTTNG tool can be > used to address. I have some time available, many years experience in > vaguely related areas and am willing to take direction. > > If my help as a developer, tester, or documenter would be appreciated, > please respond. > > regards, > Dave Brown > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 7 13:34:00 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 7 Nov 2012 13:34:00 -0500 Subject: [lttng-dev] Fix filter: pointer to string, not string, should be on stack -- query In-Reply-To: <509A0F80.1070308@quantum.com> References: <509A0F80.1070308@quantum.com> Message-ID: <20121107183400.GA29766@Krystal> * David Bryant (david.bryant at quantum.com) wrote: > Hi, > > I'm trying to understand the following changeset: > Hello ! Please upstream lttng-ust master branch HEAD, which includes this commit: commit c4261b0aecaf281fc1ced4c7af96b1ff6d2600d7 Author: Mathieu Desnoyers Date: Wed Nov 7 13:24:58 2012 -0500 Fix: re-allow non-lvalue string, sequence, array parameters Issue introduced by upstream commit: commit 27f4b6094f399f2fe231b58801dce98cbd21baa9 Author: Mathieu Desnoyers Date: Tue Sep 4 12:17:07 2012 -0400 Fix filter: pointer to string, not string, should be on stack Fixes #329 Reported-by: David Bryant Signed-off-by: Mathieu Desnoyers Please let me know if it helps, Thanks, Mathieu > commit 27f4b6094f399f2fe231b58801dce98cbd21baa9 > Author: Mathieu Desnoyers > Date: Tue Sep 4 12:17:07 2012 -0400 > > Fix filter: pointer to string, not string, should be on stack > > Fixes #329 > > Signed-off-by: Mathieu Desnoyers > > Bug link: https://bugs.lttng.org/issues/329 > > The patch forces the ctf_string() argument to be an lvalue. It appears > to be in support of tracepoint filtering of the sort: > > lttng enable-event ust_tests_demo2:loop -u --filter 'stringfield=="text"' > > Because the argument must be an lvalue the examples/easy-ust won't > compile (anymore) with the following patch: > > diff -u --recursive easy-ust/sample_component_provider.h > easy-ust-reproduce/sample_component_provider.h > --- easy-ust/sample_component_provider.h 2012-11-07 17:00:09.879299565 +1030 > +++ easy-ust-reproduce/sample_component_provider.h 2012-11-07 > 16:57:02.121647871 +1030 > @@ -61,6 +61,11 @@ > */ > #include > > +#ifndef SEE_ONCE > +#define SEE_ONCE > +static inline char * echo(char * c) { return c; } > +#endif > + > /* > * The following tracepoint event writes a message (c string) into the > * field message of the trace event message in the provider > @@ -100,7 +105,7 @@ > * The ctf_string macro takes a c string and writes it into a field > * named "message" > */ > - ctf_string(message, text) > + ctf_string(message, echo(text)) > ) > ) > /* > > Compilation results in: > > $ make > gcc -I/home/dbryant/local5/include -I. -c -o sample.o sample.c > gcc -I/home/dbryant/local5/include -I. -c -o tp.o tp.c > In file included from > /home/dbryant/local5/include/lttng/ust-tracepoint-event.h:338:0, > from /home/dbryant/local5/include/lttng/tracepoint-event.h:41, > from sample_component_provider.h:140, > from tp.c:25: > ././sample_component_provider.h: In function > ?__event_prepare_filter_stack__sample_component___message?: > ././sample_component_provider.h:76:1: error: lvalue required as unary > ?&? operand > make: *** [tp.o] Error 1 > > I'm trying to make sense of all this. I've been passing > generated-on-the-fly rvalues through ctf_string() using v2.0.5 with no > (noticeable) problems. Now I can't. Should I never have been doing that, > or has this change had an unintended consequence? Admittedly I haven't > been filtering tracepoints on text criteria and am not considering > things from that angle. Should ctf_string() arguments always be string > literals?! > > Thanks, > Dave > > ---------------------------------------------------------------------- > The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 7 15:13:21 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 7 Nov 2012 15:13:21 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix cross-compile Message-ID: <20121107201321.GA31570@Krystal> configure.ac should use --target, not --host to get the target info we want to compile for. --host is for the host that does the build. Signed-off-by: Mathieu Desnoyers --- diff --git a/configure.ac b/configure.ac index a3120fc..49d324e 100644 --- a/configure.ac +++ b/configure.ac @@ -313,7 +313,7 @@ AS_ECHO("$version_description") AS_ECHO() # Target architecture we're building for -target_arch=$host_cpu +target_arch=$target_cpu [ for f in $CFLAGS; do if test $f = "-m32"; then -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Wed Nov 7 15:17:29 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 07 Nov 2012 15:17:29 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix cross-compile In-Reply-To: <20121107201321.GA31570@Krystal> References: <20121107201321.GA31570@Krystal> Message-ID: <509AC1D9.5050704@efficios.com> Merged. Thanks! Mathieu Desnoyers: > configure.ac should use --target, not --host to get the target info we > want to compile for. --host is for the host that does the build. > > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/configure.ac b/configure.ac > index a3120fc..49d324e 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -313,7 +313,7 @@ AS_ECHO("$version_description") > AS_ECHO() > > # Target architecture we're building for > -target_arch=$host_cpu > +target_arch=$target_cpu > [ > for f in $CFLAGS; do > if test $f = "-m32"; then > > From mathieu.desnoyers at efficios.com Wed Nov 7 15:28:18 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 7 Nov 2012 15:28:18 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix cross-compile In-Reply-To: <509AC1D9.5050704@efficios.com> References: <20121107201321.GA31570@Krystal> <509AC1D9.5050704@efficios.com> Message-ID: <20121107202818.GA31867@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Merged. > > Thanks! Following up our IRC discussion, this patch should be reverted. --host is appropriate for projects, --target should be used when building cross-compilers. Thanks, Mathieu > > Mathieu Desnoyers: > > configure.ac should use --target, not --host to get the target info we > > want to compile for. --host is for the host that does the build. > > > > Signed-off-by: Mathieu Desnoyers > > --- > > diff --git a/configure.ac b/configure.ac > > index a3120fc..49d324e 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -313,7 +313,7 @@ AS_ECHO("$version_description") > > AS_ECHO() > > > > # Target architecture we're building for > > -target_arch=$host_cpu > > +target_arch=$target_cpu > > [ > > for f in $CFLAGS; do > > if test $f = "-m32"; then > > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Wed Nov 7 15:33:12 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 07 Nov 2012 15:33:12 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix cross-compile In-Reply-To: <20121107202818.GA31867@Krystal> References: <20121107201321.GA31570@Krystal> <509AC1D9.5050704@efficios.com> <20121107202818.GA31867@Krystal> Message-ID: <509AC588.5090705@efficios.com> Reverted! Mathieu Desnoyers: > * David Goulet (dgoulet at efficios.com) wrote: >> Merged. >> >> Thanks! > > Following up our IRC discussion, this patch should be reverted. --host > is appropriate for projects, --target should be used when building > cross-compilers. > > Thanks, > > Mathieu > >> >> Mathieu Desnoyers: >>> configure.ac should use --target, not --host to get the target info we >>> want to compile for. --host is for the host that does the build. >>> >>> Signed-off-by: Mathieu Desnoyers >>> --- >>> diff --git a/configure.ac b/configure.ac >>> index a3120fc..49d324e 100644 >>> --- a/configure.ac >>> +++ b/configure.ac >>> @@ -313,7 +313,7 @@ AS_ECHO("$version_description") >>> AS_ECHO() >>> >>> # Target architecture we're building for >>> -target_arch=$host_cpu >>> +target_arch=$target_cpu >>> [ >>> for f in $CFLAGS; do >>> if test $f = "-m32"; then >>> >>> > From david.bryant at quantum.com Wed Nov 7 19:33:41 2012 From: david.bryant at quantum.com (David Bryant) Date: Thu, 8 Nov 2012 11:03:41 +1030 Subject: [lttng-dev] Fix filter: pointer to string, not string, should be on stack -- query In-Reply-To: <20121107183400.GA29766@Krystal> References: <509A0F80.1070308@quantum.com> <20121107183400.GA29766@Krystal> Message-ID: <509AFDE5.8090309@quantum.com> Hi Mathieu, Yes, your commit did the trick! My patched version of easy-ust (that passed an lvalue string) compiles and runs correctly. $ lttng view Trace directory: /home/dbryant/lttng-traces/sample-20121108-105753 [10:59:16.175851994] (+?.?????????) sample:3213 sample_component:message: { cpu_id = 0 }, { message = "Hello World" } [10:59:17.176018865] (+1.000166871) sample:3213 sample_component:message: { cpu_id = 0 }, { message = "Hello World" } [10:59:18.176188138] (+1.000169273) sample:3213 sample_component:message: { cpu_id = 0 }, { message = "Hello World" } Thanks for your quick response! Dave On 08/11/12 05:04, Mathieu Desnoyers wrote: > Hello ! > > Please upstream lttng-ust master branch HEAD, which includes this > commit: > > commit c4261b0aecaf281fc1ced4c7af96b1ff6d2600d7 > Author: Mathieu Desnoyers > Date: Wed Nov 7 13:24:58 2012 -0500 > > Fix: re-allow non-lvalue string, sequence, array parameters > > Issue introduced by upstream commit: > > commit 27f4b6094f399f2fe231b58801dce98cbd21baa9 > Author: Mathieu Desnoyers > Date: Tue Sep 4 12:17:07 2012 -0400 > > Fix filter: pointer to string, not string, should be on stack > > Fixes #329 > > Reported-by: David Bryant > Signed-off-by: Mathieu Desnoyers > > Please let me know if it helps, > > Thanks, > > Mathieu > ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From david.bryant at quantum.com Wed Nov 7 22:11:54 2012 From: david.bryant at quantum.com (David Bryant) Date: Thu, 8 Nov 2012 13:41:54 +1030 Subject: [lttng-dev] tracepoint provider: static versus dynamic linking (TRACEPOINT_PROBE_DYNAMIC_LINKAGE) Message-ID: <509B22FA.2030800@quantum.com> Hello, What are the pros and cons of static versus dynamic linking of the tracepoint provider? I can't find much information looking around. Are their any licensing related issues? For example, is closed-source software not allowed to use static linking? Is it just an optimisation - allowing the program to run without probes connected? Thanks, Dave Notes from my digging of how it works: Looking at the preprocessor output of sample.c without/with TRACEPOINT_PROBE_DYNAMIC_LINKAGE defined I see: $ diff -u sample.i.static sample.i.dynamic --- sample.i.static 2012-11-08 13:29:04.049059515 +1030 +++ sample.i.dynamic 2012-11-08 13:29:04.169062438 +1030 @@ -746,7 +746,7 @@ struct tracepoint __tracepoint_sample_component___message __attribute__((section("__tracepoints"))) = { __tp_strtab_sample_component___message, 0, ((void *)0), - &__tracepoint_provider_sample_component, + ((void *)0), "char *, text", }; (line breaks added by me). So the "int * tracepoint::tracepoint_provider_ref" member is set to ((void *)0) in struct tracepoint: struct tracepoint { const char *name; int state; struct tracepoint_probe *probes; int *tracepoint_provider_ref; /* XXX */ const char *signature; char padding[16]; }; So the static version is not dependent on the symbol "__tracepoint_provider_sample_component". Running LD_PRELOAD=libprovider.so ./sample (somehow?) reinstates that symbol. (Can't quite see how that works). ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From dafidbrown at gmail.com Thu Nov 8 04:02:56 2012 From: dafidbrown at gmail.com (David Brown) Date: Thu, 8 Nov 2012 09:02:56 +0000 Subject: [lttng-dev] Offering to help In-Reply-To: <20121107173355.GA28974@Krystal> References: <20121107173355.GA28974@Krystal> Message-ID: Michel and Mathieu, Thanks for the welcome messages. Perhaps since I would lie a "quick start guide" myself, I should have a look at creating one first. Is there a guide from the first version that needs updating, or is should I be looking to answer the FAQs in a structured way to guide people to a quick happy result? Dave On 7 November 2012 17:33, Mathieu Desnoyers wrote: > Hi David! > > Glad to see you are interested in helping us :) I see you are on oftc > #lttng, which is indeed the right first step. > > We have plently of things to work on in this project in all your areas > of expertise. One that come up to my mind, and have been bugging me for > a while, is that we lack a sort of "quickstart guide" for lttng 2.x. A > new user has only manpages (and --help) to refer to, but there is no > comprehensive document that get people up and running quickly. Is this > something you would be interested to contribute ? Proposing it on > lttng-dev should help you get feedback. > > Other than that, a second step would be to look at the bug tracker: > bugs.lttng.org , especially the "feature requests" and some low priority > bugs that are sitting there. If anything catch your interest, it could > be a nice way to dig into the project. > > Thanks! > > Mathieu > > * David Brown (dafidbrown at gmail.com) wrote: >> Hello folks, >> >> I am interested in some of the problems that the LTTNG tool can be >> used to address. I have some time available, many years experience in >> vaguely related areas and am willing to take direction. >> >> If my help as a developer, tester, or documenter would be appreciated, >> please respond. >> >> regards, >> Dave Brown >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Nov 8 09:22:57 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 8 Nov 2012 09:22:57 -0500 Subject: [lttng-dev] Offering to help In-Reply-To: References: <20121107173355.GA28974@Krystal> Message-ID: <20121108142257.GA13121@Krystal> * David Brown (dafidbrown at gmail.com) wrote: > Michel and Mathieu, > > Thanks for the welcome messages. Perhaps since I would lie a "quick > start guide" myself, I should have a look at creating one first. Is > there a guide from the first version that needs updating, or is should > I be looking to answer the FAQs in a structured way to guide people to > a quick happy result? Hi David, There is currently a "Getting Started" page for lttng 2.x (http://lttng.org/quickstart), but I think it should be enhanced. For instance, when stating "First make sure you have lttng-modules (the kernel modules) and lttng-tools installed.", we should probably provide pointers to README files of individual projects for installation directives. The goal is to come up with a very concise document that contains pointers to reach all the detailed information that users might be looking for through their first steps with lttng. Maybe some of the extended quickstart guide at https://bugs.lttng.org/projects/lttng-tools/wiki (refered to by the first one) might be the right one to expand though. If you feel we need to promote this guide with a link in the documentation page or elsewhere, please let us know, Thanks! Mathieu > > Dave > > > On 7 November 2012 17:33, Mathieu Desnoyers > wrote: > > Hi David! > > > > Glad to see you are interested in helping us :) I see you are on oftc > > #lttng, which is indeed the right first step. > > > > We have plently of things to work on in this project in all your areas > > of expertise. One that come up to my mind, and have been bugging me for > > a while, is that we lack a sort of "quickstart guide" for lttng 2.x. A > > new user has only manpages (and --help) to refer to, but there is no > > comprehensive document that get people up and running quickly. Is this > > something you would be interested to contribute ? Proposing it on > > lttng-dev should help you get feedback. > > > > Other than that, a second step would be to look at the bug tracker: > > bugs.lttng.org , especially the "feature requests" and some low priority > > bugs that are sitting there. If anything catch your interest, it could > > be a nice way to dig into the project. > > > > Thanks! > > > > Mathieu > > > > * David Brown (dafidbrown at gmail.com) wrote: > >> Hello folks, > >> > >> I am interested in some of the problems that the LTTNG tool can be > >> used to address. I have some time available, many years experience in > >> vaguely related areas and am willing to take direction. > >> > >> If my help as a developer, tester, or documenter would be appreciated, > >> please respond. > >> > >> regards, > >> Dave Brown > >> > >> _______________________________________________ > >> lttng-dev mailing list > >> lttng-dev at lists.lttng.org > >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From christian.babeux at efficios.com Thu Nov 8 14:13:25 2012 From: christian.babeux at efficios.com (Christian Babeux) Date: Thu, 8 Nov 2012 14:13:25 -0500 Subject: [lttng-dev] [PATCH urcu] Fix: Fallback mechanism not working on platform where TLS is unsupported Message-ID: <1352402005-26604-1-git-send-email-christian.babeux@efficios.com> The CONFIG_RCU_TLS entry in config.h.in is defined by default to "TLS". This has the unfortunate consequence of defining CONFIG_RCU_TLS on platform where TLS is unsupported and effectively disabling the pthread based fallback mechanism. This macro should be #undef by default and the AX_TLS m4 macro will properly detect if TLS is supported. Signed-off-by: Christian Babeux --- urcu/config.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/urcu/config.h.in b/urcu/config.h.in index de1d1d0..98ea365 100644 --- a/urcu/config.h.in +++ b/urcu/config.h.in @@ -18,4 +18,4 @@ #undef CONFIG_RCU_ARM_HAVE_DMB /* TLS provided by the compiler. */ -#define CONFIG_RCU_TLS TLS +#undef CONFIG_RCU_TLS -- 1.8.0 From mathieu.desnoyers at efficios.com Thu Nov 8 14:31:11 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 8 Nov 2012 14:31:11 -0500 Subject: [lttng-dev] [PATCH urcu] Fix: Fallback mechanism not working on platform where TLS is unsupported In-Reply-To: <1352402005-26604-1-git-send-email-christian.babeux@efficios.com> References: <1352402005-26604-1-git-send-email-christian.babeux@efficios.com> Message-ID: <20121108193111.GB20848@Krystal> * Christian Babeux (christian.babeux at efficios.com) wrote: > The CONFIG_RCU_TLS entry in config.h.in is defined by default to "TLS". > This has the unfortunate consequence of defining CONFIG_RCU_TLS on platform > where TLS is unsupported and effectively disabling the pthread based > fallback mechanism. This macro should be #undef by default and the > AX_TLS m4 macro will properly detect if TLS is supported. merged, thanks! Mathieu > > Signed-off-by: Christian Babeux > --- > urcu/config.h.in | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/urcu/config.h.in b/urcu/config.h.in > index de1d1d0..98ea365 100644 > --- a/urcu/config.h.in > +++ b/urcu/config.h.in > @@ -18,4 +18,4 @@ > #undef CONFIG_RCU_ARM_HAVE_DMB > > /* TLS provided by the compiler. */ > -#define CONFIG_RCU_TLS TLS > +#undef CONFIG_RCU_TLS > -- > 1.8.0 > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Thu Nov 8 15:17:18 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Thu, 8 Nov 2012 15:17:18 -0500 Subject: [lttng-dev] [PATCH] Check if interrupt action name is not null in statedump. Message-ID: <1352405838-5687-1-git-send-email-simon.marchi@polymtl.ca> Protection against poorly written drivers who give a null name to their irq handlers. Signed-off-by: Simon Marchi --- .../events/lttng-module/lttng-statedump.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/events/lttng-module/lttng-statedump.h b/instrumentation/events/lttng-module/lttng-statedump.h index d350cad..e4c86d6 100644 --- a/instrumentation/events/lttng-module/lttng-statedump.h +++ b/instrumentation/events/lttng-module/lttng-statedump.h @@ -150,12 +150,12 @@ TRACE_EVENT(lttng_statedump_interrupt, TP_STRUCT__entry( __field(unsigned int, irq) __string(name, chip_name) - __string(action, action->name) + __string(action, action->name ? : "") ), TP_fast_assign( tp_assign(irq, irq) tp_strcpy(name, chip_name) - tp_strcpy(action, action->name) + tp_strcpy(action, action->name ? : "") ), TP_printk("") ) -- 1.7.1 From mathieu.desnoyers at efficios.com Thu Nov 8 15:18:47 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 8 Nov 2012 15:18:47 -0500 Subject: [lttng-dev] [PATCH] Check if interrupt action name is not null in statedump. In-Reply-To: <1352405838-5687-1-git-send-email-simon.marchi@polymtl.ca> References: <1352405838-5687-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121108201847.GA21370@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Protection against poorly written drivers who give a null name to their > irq handlers. > > Signed-off-by: Simon Marchi merged, thanks! Mathieu > --- > .../events/lttng-module/lttng-statedump.h | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/instrumentation/events/lttng-module/lttng-statedump.h b/instrumentation/events/lttng-module/lttng-statedump.h > index d350cad..e4c86d6 100644 > --- a/instrumentation/events/lttng-module/lttng-statedump.h > +++ b/instrumentation/events/lttng-module/lttng-statedump.h > @@ -150,12 +150,12 @@ TRACE_EVENT(lttng_statedump_interrupt, > TP_STRUCT__entry( > __field(unsigned int, irq) > __string(name, chip_name) > - __string(action, action->name) > + __string(action, action->name ? : "") > ), > TP_fast_assign( > tp_assign(irq, irq) > tp_strcpy(name, chip_name) > - tp_strcpy(action, action->name) > + tp_strcpy(action, action->name ? : "") > ), > TP_printk("") > ) > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Nov 8 21:54:18 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 8 Nov 2012 21:54:18 -0500 Subject: [lttng-dev] [urcu commit] Fix TLS detection: test with linker, add --disable-compiler-tls Message-ID: <20121109025418.GA26014@Krystal> The following commit is now in the userspace RCU master branch (backported to stable-0.7 branch too). It should fix TLS detection on both NetBSD <= 5.1, and on Darwin, and adds a --disable-compiler-tls flag to force using the pthread_getspecific fallback. commit 75478b32ffe53b0d8b5e687d9cf7ebdd77a085de Author: Mathieu Desnoyers Date: Thu Nov 8 21:45:04 2012 -0500 Fix TLS detection: test with linker, add --disable-compiler-tls NetBSD 5.1 and older, as well as Darwin, succeed to compile code containing TLS, but cannot link it. Test with linker in addition to compiler for TLS support. Also add a --disable-compiler-tls configure option to allow users to force using the pthread getspecific fall back. Fixes #288 Signed-off-by: Mathieu Desnoyers Feedback is welcome! Thanks, Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Fri Nov 9 01:39:06 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 9 Nov 2012 01:39:06 -0500 Subject: [lttng-dev] [PATCH 1/3] Add default subbuf sizes getter functions. Message-ID: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> This patch adds src/common/defaults.c file. It contains functions to retrieve defaults subbuf sizes based on the architecture page size. Signed-off-by: Simon Marchi --- src/common/Makefile.am | 2 +- src/common/defaults.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/common/defaults.h | 7 ++++ 3 files changed, 94 insertions(+), 1 deletions(-) create mode 100644 src/common/defaults.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b43b376..f91259c 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ - common.h futex.c futex.h uri.c uri.h + common.h futex.c futex.h uri.c uri.h defaults.c # Consumer library noinst_LTLIBRARIES += libconsumer.la diff --git a/src/common/defaults.c b/src/common/defaults.c new file mode 100644 index 0000000..48d6605 --- /dev/null +++ b/src/common/defaults.c @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 - Simon Marchi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "defaults.h" + +static size_t default_channel_subbuf_size; +static size_t default_metadata_subbuf_size; +static size_t default_kernel_channel_subbuf_size; +static size_t default_ust_channel_subbuf_size; + +static void __attribute__((constructor)) init_defaults(void) +{ + default_kernel_channel_subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + + long page_size = sysconf(_SC_PAGESIZE); + if (page_size > 0) { + default_channel_subbuf_size = page_size; + default_metadata_subbuf_size = page_size; + default_ust_channel_subbuf_size = page_size; + } else { + default_channel_subbuf_size = 4096; + default_metadata_subbuf_size = 4096; + default_ust_channel_subbuf_size = 4096; + } +} + +/* + * Returns the default subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t get_default_channel_subbuf_size(void) +{ + return default_channel_subbuf_size; +} + +/* + * Returns the default metadata subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t get_default_metadata_subbuf_size(void) +{ + return default_metadata_subbuf_size; +} + +/* + * Returns the default subbuf size for the kernel domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t get_default_kernel_channel_subbuf_size(void) +{ + return default_kernel_channel_subbuf_size; +} + +/* + * Returns the default subbuf size for the UST domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t get_default_ust_channel_subbuf_size(void) +{ + return default_ust_channel_subbuf_size; +} diff --git a/src/common/defaults.h b/src/common/defaults.h index 0c0b6ac..efff43e 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -109,6 +109,9 @@ #define DEFAULT_METADATA_SUBBUF_SIZE 4096 #define DEFAULT_METADATA_SUBBUF_NUM 2 +size_t get_default_channel_subbuf_size(void); +size_t get_default_metadata_subbuf_size(void); + /* Kernel has different defaults */ /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ @@ -121,6 +124,8 @@ /* See lttng-kernel.h enum lttng_kernel_output for channel output */ #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE +size_t get_default_kernel_channel_subbuf_size(void); + /* User space defaults */ /* Must be a power of 2 */ @@ -130,6 +135,8 @@ /* See lttng-ust.h enum lttng_ust_output */ #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP +size_t get_default_ust_channel_subbuf_size(void); + /* * Default timeout value for the sem_timedwait() call. Blocking forever is not * wanted so a timeout is used to control the data flow and not freeze the -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 9 01:39:07 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 9 Nov 2012 01:39:07 -0500 Subject: [lttng-dev] [PATCH 2/3] Use the new functions for default subbuf sizes. In-Reply-To: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> References: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352443148-7135-2-git-send-email-simon.marchi@polymtl.ca> Use the functions added by the previous commit. All the occurences of the previous defines were replaced. Signed-off-by: Simon Marchi --- src/bin/lttng-sessiond/channel.c | 4 ++-- src/bin/lttng-sessiond/trace-kernel.c | 2 +- src/bin/lttng-sessiond/trace-ust.c | 2 +- src/bin/lttng/commands/enable_channels.c | 6 +++--- src/lib/lttng-ctl/lttng-ctl.c | 4 ++-- tests/tools/Makefile.am | 2 +- tests/tools/test_kernel_data_trace.c | 2 +- tests/tools/test_ust_data_trace.c | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index e2cdf56..9f6b821 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -54,7 +54,7 @@ struct lttng_channel *channel_new_default_attr(int dom) switch (dom) { case LTTNG_DOMAIN_KERNEL: - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = get_default_kernel_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -64,7 +64,7 @@ struct lttng_channel *channel_new_default_attr(int dom) case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: case LTTNG_DOMAIN_UST_EXEC_NAME: #endif - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = get_default_ust_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 7748b89..3145565 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -272,7 +272,7 @@ struct ltt_kernel_metadata *trace_kernel_create_metadata(void) /* Set default attributes */ chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.subbuf_size = get_default_metadata_subbuf_size(); chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 864a4b0..897149a 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -311,7 +311,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) /* Set default attributes */ lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + lum->attr.subbuf_size = get_default_metadata_subbuf_size(); lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 1857477..2a29218 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -101,9 +101,9 @@ static void usage(FILE *ofp) fprintf(ofp, " --overwrite Flight recorder mode%s\n", DEFAULT_CHANNEL_OVERWRITE ? " (default)" : ""); fprintf(ofp, " --subbuf-size SIZE Subbuffer size in bytes\n"); - fprintf(ofp, " (default: %u, kernel default: %u)\n", - DEFAULT_CHANNEL_SUBBUF_SIZE, - DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); + fprintf(ofp, " (default: %zu, kernel default: %zu)\n", + get_default_channel_subbuf_size(), + get_default_kernel_channel_subbuf_size()); fprintf(ofp, " Needs to be a power of 2 for\n"); fprintf(ofp, " kernel and ust tracers\n"); fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 46338fb..34fdfb8 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1344,7 +1344,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = get_default_kernel_channel_subbuf_size(); attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -1358,7 +1358,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = get_default_ust_channel_subbuf_size(); attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am index cd7ff32..4fe494c 100644 --- a/tests/tools/Makefile.am +++ b/tests/tools/Makefile.am @@ -27,7 +27,7 @@ test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM) # Kernel trace data unit tests test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE) -test_kernel_data_trace_LDADD = $(SESSIOND_COMM) $(HASHTABLE) +test_kernel_data_trace_LDADD = $(COMMON) $(SESSIOND_COMM) $(HASHTABLE) if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += test_ust_data_trace diff --git a/tests/tools/test_kernel_data_trace.c b/tests/tools/test_kernel_data_trace.c index c49d7ce..27638b5 100644 --- a/tests/tools/test_kernel_data_trace.c +++ b/tests/tools/test_kernel_data_trace.c @@ -99,7 +99,7 @@ static void create_kernel_metadata(void) assert(kern->metadata->conf->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(kern->metadata->conf->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == get_default_metadata_subbuf_size()); assert(kern->metadata->conf->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(kern->metadata->conf->attr.switch_timer_interval diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c index 459520d..4a2c7e3 100644 --- a/tests/tools/test_ust_data_trace.c +++ b/tests/tools/test_ust_data_trace.c @@ -107,7 +107,7 @@ static void create_ust_metadata(void) assert(metadata->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(metadata->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == get_default_metadata_subbuf_size()); assert(metadata->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(metadata->attr.switch_timer_interval -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 9 01:39:08 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 9 Nov 2012 01:39:08 -0500 Subject: [lttng-dev] [PATCH 3/3] Remove previous default subbuf sizes definitions. In-Reply-To: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> References: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352443148-7135-3-git-send-email-simon.marchi@polymtl.ca> This commit removes defines that are now unused. Signed-off-by: Simon Marchi --- src/common/defaults.h | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/src/common/defaults.h b/src/common/defaults.h index efff43e..7319b35 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -98,15 +98,12 @@ /* Default channel attributes */ #define DEFAULT_CHANNEL_NAME "channel0" #define DEFAULT_CHANNEL_OVERWRITE 0 /* usec */ -/* DEFAULT_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ -#define DEFAULT_CHANNEL_SUBBUF_SIZE 4096 /* bytes */ /* DEFAULT_CHANNEL_SUBBUF_NUM must always be a power of 2 */ #define DEFAULT_CHANNEL_SUBBUF_NUM 4 #define DEFAULT_CHANNEL_SWITCH_TIMER 0 /* usec */ #define DEFAULT_CHANNEL_READ_TIMER 200 /* usec */ #define DEFAULT_CHANNEL_OUTPUT LTTNG_EVENT_MMAP -#define DEFAULT_METADATA_SUBBUF_SIZE 4096 #define DEFAULT_METADATA_SUBBUF_NUM 2 size_t get_default_channel_subbuf_size(void); @@ -128,8 +125,6 @@ size_t get_default_kernel_channel_subbuf_size(void); /* User space defaults */ -/* Must be a power of 2 */ -#define DEFAULT_UST_CHANNEL_SUBBUF_SIZE 4096 /* bytes */ /* Must be a power of 2. Update help manuall if override. */ #define DEFAULT_UST_CHANNEL_SUBBUF_NUM DEFAULT_CHANNEL_SUBBUF_NUM /* See lttng-ust.h enum lttng_ust_output */ -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 9 01:46:54 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 9 Nov 2012 01:46:54 -0500 Subject: [lttng-dev] [PATCH urcu] Add compilation support for the TileGX architecture. Message-ID: <1352443614-8272-1-git-send-email-simon.marchi@polymtl.ca> Signed-off-by: Simon Marchi --- configure.ac | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index 1d04062..a4ef8c9 100644 --- a/configure.ac +++ b/configure.ac @@ -77,6 +77,7 @@ AS_CASE([$host_cpu], [ia64], [ARCHTYPE="gcc"], [arm*], [ARCHTYPE="arm"], [mips*], [ARCHTYPE="mips"], + [tile], [ARCHTYPE="gcc"], [ARCHTYPE="unknown"] ) -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 9 01:48:31 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 9 Nov 2012 01:48:31 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Add compilation support for the TileGX architecture. Message-ID: <1352443711-8662-1-git-send-email-simon.marchi@polymtl.ca> Signed-off-by: Simon Marchi --- configure.ac | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index 7f12f23..97a9f65 100644 --- a/configure.ac +++ b/configure.ac @@ -213,6 +213,7 @@ changequote([,])dnl armv5) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; arm) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; mips*) LIBFORMAT=""; NO_UNALIGNED_ACCESS=1;; + tile) LIBFORMAT="elf64-tilegx-le"; NO_UNALIGNED_ACCESS=1;; *) AC_MSG_ERROR([unable to detect library format (unsupported architecture ($host_cpu)?)]) ;; esac AC_SUBST(LIBFORMAT) -- 1.7.1 From marek.vavrusa at nic.cz Fri Nov 9 03:22:25 2012 From: marek.vavrusa at nic.cz (=?UTF-8?Q?Marek_Vavru=C5=A1a?=) Date: Fri, 9 Nov 2012 09:22:25 +0100 Subject: [lttng-dev] [urcu commit] Fix TLS detection: test with linker, add --disable-compiler-tls In-Reply-To: <20121109025418.GA26014@Krystal> References: <20121109025418.GA26014@Krystal> Message-ID: Nice, I can confirm it compiles on OSX10.8 with default gcc and autodisables __thread correctly. It also builds with clang, __thread enabled/disabled. For backported 0.7, i think the patch for MAP_ANONYMOUS compatibility needs to be backported as well (if it's not already). Great work, thanks! Marek On 9 November 2012 03:54, Mathieu Desnoyers wrote: > The following commit is now in the userspace RCU master branch > (backported to stable-0.7 branch too). It should fix TLS detection on > both NetBSD <= 5.1, and on Darwin, and adds a --disable-compiler-tls > flag to force using the pthread_getspecific fallback. > > > commit 75478b32ffe53b0d8b5e687d9cf7ebdd77a085de > Author: Mathieu Desnoyers > Date: Thu Nov 8 21:45:04 2012 -0500 > > Fix TLS detection: test with linker, add --disable-compiler-tls > > NetBSD 5.1 and older, as well as Darwin, succeed to compile code > containing TLS, but cannot link it. Test with linker in addition to > compiler for TLS support. > > Also add a --disable-compiler-tls configure option to allow users to > force using the pthread getspecific fall back. > > Fixes #288 > > Signed-off-by: Mathieu Desnoyers > > Feedback is welcome! > > Thanks, > > Mathieu > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From luis at cs.umu.se Fri Nov 9 07:15:24 2012 From: luis at cs.umu.se (Luis) Date: Fri, 09 Nov 2012 13:15:24 +0100 Subject: [lttng-dev] Measure network usage Message-ID: <509CF3DC.7010700@cs.umu.se> Hello! I would like to know how can I measure the network usage of an application (when and during how much time) by using LTTng software! Thank you, Luis From mathieu.desnoyers at efficios.com Fri Nov 9 10:29:10 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 9 Nov 2012 10:29:10 -0500 Subject: [lttng-dev] [urcu commit] Fix TLS detection: test with linker, add --disable-compiler-tls In-Reply-To: References: <20121109025418.GA26014@Krystal> Message-ID: <20121109152910.GA6675@Krystal> * Marek Vavru?a (marek.vavrusa at nic.cz) wrote: > Nice, I can confirm it compiles on OSX10.8 with default gcc and > autodisables __thread correctly. > It also builds with clang, __thread enabled/disabled. Excellent news! > For backported 0.7, i think the patch for MAP_ANONYMOUS compatibility needs > to be backported as well (if it's not already). If you mean this patch: commit 0d0cf93f74adf0367b3f9d007351984e91d6e91f Author: Mathieu Desnoyers Date: Sat May 26 11:00:16 2012 -0400 freebsd 8.2 fix: define MAP_ANONYMOUS for compatibility Signed-off-by: Mathieu Desnoyers It was merged between 0.7.2 and 0.7.3, so it's part of both stable-0.7 and master branches. Hopefully I'm not missing another one. Thanks! Mathieu > Great work, thanks! > > Marek > > On 9 November 2012 03:54, Mathieu Desnoyers > wrote: > > > The following commit is now in the userspace RCU master branch > > (backported to stable-0.7 branch too). It should fix TLS detection on > > both NetBSD <= 5.1, and on Darwin, and adds a --disable-compiler-tls > > flag to force using the pthread_getspecific fallback. > > > > > > commit 75478b32ffe53b0d8b5e687d9cf7ebdd77a085de > > Author: Mathieu Desnoyers > > Date: Thu Nov 8 21:45:04 2012 -0500 > > > > Fix TLS detection: test with linker, add --disable-compiler-tls > > > > NetBSD 5.1 and older, as well as Darwin, succeed to compile code > > containing TLS, but cannot link it. Test with linker in addition to > > compiler for TLS support. > > > > Also add a --disable-compiler-tls configure option to allow users to > > force using the pthread getspecific fall back. > > > > Fixes #288 > > > > Signed-off-by: Mathieu Desnoyers > > > > Feedback is welcome! > > > > Thanks, > > > > Mathieu > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Fri Nov 9 10:52:51 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 09 Nov 2012 10:52:51 -0500 Subject: [lttng-dev] [PATCH 1/3] Add default subbuf sizes getter functions. In-Reply-To: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> References: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <509D26D3.4070609@efficios.com> Hi Simon, Can you please rename the get_default_* function family to default_get_* in order to respect the name spacing of files. Comment below: Simon Marchi: > This patch adds src/common/defaults.c file. It contains functions to > retrieve defaults subbuf sizes based on the architecture page size. > > Signed-off-by: Simon Marchi > --- > src/common/Makefile.am | 2 +- > src/common/defaults.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ > src/common/defaults.h | 7 ++++ > 3 files changed, 94 insertions(+), 1 deletions(-) > create mode 100644 src/common/defaults.c > > diff --git a/src/common/Makefile.am b/src/common/Makefile.am > index b43b376..f91259c 100644 > --- a/src/common/Makefile.am > +++ b/src/common/Makefile.am > @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ > noinst_LTLIBRARIES = libcommon.la > > libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ > - common.h futex.c futex.h uri.c uri.h > + common.h futex.c futex.h uri.c uri.h defaults.c > > # Consumer library > noinst_LTLIBRARIES += libconsumer.la > diff --git a/src/common/defaults.c b/src/common/defaults.c > new file mode 100644 > index 0000000..48d6605 > --- /dev/null > +++ b/src/common/defaults.c > @@ -0,0 +1,86 @@ > +/* > + * Copyright (C) 2012 - Simon Marchi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License, version 2 only, > + * as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include > +#include > + > +#include "defaults.h" > + > +static size_t default_channel_subbuf_size; > +static size_t default_metadata_subbuf_size; > +static size_t default_kernel_channel_subbuf_size; > +static size_t default_ust_channel_subbuf_size; > + > +static void __attribute__((constructor)) init_defaults(void) > +{ > + default_kernel_channel_subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; Why is the kernel getting a default value and not a page size ? > + > + long page_size = sysconf(_SC_PAGESIZE); > + if (page_size > 0) { > + default_channel_subbuf_size = page_size; > + default_metadata_subbuf_size = page_size; > + default_ust_channel_subbuf_size = page_size; > + } else { > + default_channel_subbuf_size = 4096; > + default_metadata_subbuf_size = 4096; > + default_ust_channel_subbuf_size = 4096; Should we use a default value for this 4096 size here with a DEFINE_*_SUBBUF_SIZE or... ? Seems a bit odd that the kernel got a default define value but not UST and metadata. > + } > +} > + > +/* > + * Returns the default subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t get_default_channel_subbuf_size(void) > +{ > + return default_channel_subbuf_size; > +} > + > +/* > + * Returns the default metadata subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t get_default_metadata_subbuf_size(void) > +{ > + return default_metadata_subbuf_size; > +} > + > +/* > + * Returns the default subbuf size for the kernel domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t get_default_kernel_channel_subbuf_size(void) > +{ > + return default_kernel_channel_subbuf_size; > +} > + > +/* > + * Returns the default subbuf size for the UST domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t get_default_ust_channel_subbuf_size(void) > +{ > + return default_ust_channel_subbuf_size; > +} I'm wondering if all these functions should be static inline in the default.h... Thoughts? Otherwise, the patch looks good! Thanks David > diff --git a/src/common/defaults.h b/src/common/defaults.h > index 0c0b6ac..efff43e 100644 > --- a/src/common/defaults.h > +++ b/src/common/defaults.h > @@ -109,6 +109,9 @@ > #define DEFAULT_METADATA_SUBBUF_SIZE 4096 > #define DEFAULT_METADATA_SUBBUF_NUM 2 > > +size_t get_default_channel_subbuf_size(void); > +size_t get_default_metadata_subbuf_size(void); > + > /* Kernel has different defaults */ > > /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ > @@ -121,6 +124,8 @@ > /* See lttng-kernel.h enum lttng_kernel_output for channel output */ > #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE > > +size_t get_default_kernel_channel_subbuf_size(void); > + > /* User space defaults */ > > /* Must be a power of 2 */ > @@ -130,6 +135,8 @@ > /* See lttng-ust.h enum lttng_ust_output */ > #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP > > +size_t get_default_ust_channel_subbuf_size(void); > + > /* > * Default timeout value for the sem_timedwait() call. Blocking forever is not > * wanted so a timeout is used to control the data flow and not freeze the From mathieu.desnoyers at efficios.com Fri Nov 9 10:54:39 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 9 Nov 2012 10:54:39 -0500 Subject: [lttng-dev] [PATCH 1/3] Add default subbuf sizes getter functions. In-Reply-To: <509D26D3.4070609@efficios.com> References: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> <509D26D3.4070609@efficios.com> Message-ID: <20121109155439.GA8094@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Hi Simon, > > Can you please rename the get_default_* function family to default_get_* > in order to respect the name spacing of files. Also, Simon, please remove the "dot" at the end of the Title line of your patch. Thanks, Mathieu > > Comment below: > > Simon Marchi: > > This patch adds src/common/defaults.c file. It contains functions to > > retrieve defaults subbuf sizes based on the architecture page size. > > > > Signed-off-by: Simon Marchi > > --- > > src/common/Makefile.am | 2 +- > > src/common/defaults.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ > > src/common/defaults.h | 7 ++++ > > 3 files changed, 94 insertions(+), 1 deletions(-) > > create mode 100644 src/common/defaults.c > > > > diff --git a/src/common/Makefile.am b/src/common/Makefile.am > > index b43b376..f91259c 100644 > > --- a/src/common/Makefile.am > > +++ b/src/common/Makefile.am > > @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ > > noinst_LTLIBRARIES = libcommon.la > > > > libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ > > - common.h futex.c futex.h uri.c uri.h > > + common.h futex.c futex.h uri.c uri.h defaults.c > > > > # Consumer library > > noinst_LTLIBRARIES += libconsumer.la > > diff --git a/src/common/defaults.c b/src/common/defaults.c > > new file mode 100644 > > index 0000000..48d6605 > > --- /dev/null > > +++ b/src/common/defaults.c > > @@ -0,0 +1,86 @@ > > +/* > > + * Copyright (C) 2012 - Simon Marchi > > + * > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License, version 2 only, > > + * as published by the Free Software Foundation. > > + * > > + * This program is distributed in the hope that it will be useful, but WITHOUT > > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > > + * more details. > > + * > > + * You should have received a copy of the GNU General Public License along > > + * with this program; if not, write to the Free Software Foundation, Inc., > > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > > + */ > > + > > +#include > > +#include > > + > > +#include "defaults.h" > > + > > +static size_t default_channel_subbuf_size; > > +static size_t default_metadata_subbuf_size; > > +static size_t default_kernel_channel_subbuf_size; > > +static size_t default_ust_channel_subbuf_size; > > + > > +static void __attribute__((constructor)) init_defaults(void) > > +{ > > + default_kernel_channel_subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; > > Why is the kernel getting a default value and not a page size ? > > > + > > + long page_size = sysconf(_SC_PAGESIZE); > > + if (page_size > 0) { > > + default_channel_subbuf_size = page_size; > > + default_metadata_subbuf_size = page_size; > > + default_ust_channel_subbuf_size = page_size; > > + } else { > > + default_channel_subbuf_size = 4096; > > + default_metadata_subbuf_size = 4096; > > + default_ust_channel_subbuf_size = 4096; > > Should we use a default value for this 4096 size here with a > DEFINE_*_SUBBUF_SIZE or... ? > > Seems a bit odd that the kernel got a default define value but not UST > and metadata. > > > + } > > +} > > + > > +/* > > + * Returns the default subbuf size. > > + * > > + * This function depends on a value that is set at constructor time, so it is > > + * unsafe to call it from another constructor. > > + */ > > +size_t get_default_channel_subbuf_size(void) > > +{ > > + return default_channel_subbuf_size; > > +} > > + > > +/* > > + * Returns the default metadata subbuf size. > > + * > > + * This function depends on a value that is set at constructor time, so it is > > + * unsafe to call it from another constructor. > > + */ > > +size_t get_default_metadata_subbuf_size(void) > > +{ > > + return default_metadata_subbuf_size; > > +} > > + > > +/* > > + * Returns the default subbuf size for the kernel domain. > > + * > > + * This function depends on a value that is set at constructor time, so it is > > + * unsafe to call it from another constructor. > > + */ > > +size_t get_default_kernel_channel_subbuf_size(void) > > +{ > > + return default_kernel_channel_subbuf_size; > > +} > > + > > +/* > > + * Returns the default subbuf size for the UST domain. > > + * > > + * This function depends on a value that is set at constructor time, so it is > > + * unsafe to call it from another constructor. > > + */ > > +size_t get_default_ust_channel_subbuf_size(void) > > +{ > > + return default_ust_channel_subbuf_size; > > +} > > I'm wondering if all these functions should be static inline in the > default.h... > > Thoughts? > > Otherwise, the patch looks good! > > Thanks > David > > > diff --git a/src/common/defaults.h b/src/common/defaults.h > > index 0c0b6ac..efff43e 100644 > > --- a/src/common/defaults.h > > +++ b/src/common/defaults.h > > @@ -109,6 +109,9 @@ > > #define DEFAULT_METADATA_SUBBUF_SIZE 4096 > > #define DEFAULT_METADATA_SUBBUF_NUM 2 > > > > +size_t get_default_channel_subbuf_size(void); > > +size_t get_default_metadata_subbuf_size(void); > > + > > /* Kernel has different defaults */ > > > > /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ > > @@ -121,6 +124,8 @@ > > /* See lttng-kernel.h enum lttng_kernel_output for channel output */ > > #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE > > > > +size_t get_default_kernel_channel_subbuf_size(void); > > + > > /* User space defaults */ > > > > /* Must be a power of 2 */ > > @@ -130,6 +135,8 @@ > > /* See lttng-ust.h enum lttng_ust_output */ > > #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP > > > > +size_t get_default_ust_channel_subbuf_size(void); > > + > > /* > > * Default timeout value for the sem_timedwait() call. Blocking forever is not > > * wanted so a timeout is used to control the data flow and not freeze the > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri Nov 9 10:57:31 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 9 Nov 2012 10:57:31 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Add compilation support for the TileGX architecture. In-Reply-To: <1352443711-8662-1-git-send-email-simon.marchi@polymtl.ca> References: <1352443711-8662-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121109155731.GB8094@Krystal> First detail: please remove dot from subject end of line. * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Signed-off-by: Simon Marchi > --- > configure.ac | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 7f12f23..97a9f65 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -213,6 +213,7 @@ changequote([,])dnl > armv5) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > arm) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > mips*) LIBFORMAT=""; NO_UNALIGNED_ACCESS=1;; > + tile) LIBFORMAT="elf64-tilegx-le"; NO_UNALIGNED_ACCESS=1;; Not sure how this works, but I think there exists other "tile" flavors out there besides the tilegx. Will they appear as "tile" from an autotools point of view and then break when we specify their libformat as elf64-tilegx-le ? Are there any way to distinguish between flavors ? Please ask advice to Tilera if needed. Thanks, Mathieu > *) AC_MSG_ERROR([unable to detect library format (unsupported architecture ($host_cpu)?)]) ;; > esac > AC_SUBST(LIBFORMAT) > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri Nov 9 10:58:46 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 9 Nov 2012 10:58:46 -0500 Subject: [lttng-dev] [PATCH urcu] Add compilation support for the TileGX architecture. In-Reply-To: <1352443614-8272-1-git-send-email-simon.marchi@polymtl.ca> References: <1352443614-8272-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121109155846.GC8094@Krystal> should remove dot from EOL too. * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Signed-off-by: Simon Marchi > --- > configure.ac | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 1d04062..a4ef8c9 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -77,6 +77,7 @@ AS_CASE([$host_cpu], > [ia64], [ARCHTYPE="gcc"], > [arm*], [ARCHTYPE="arm"], > [mips*], [ARCHTYPE="mips"], > + [tile], [ARCHTYPE="gcc"], So I guess you are adding support for the Tile architecture, not just the TileGX. Can you resumbit after updating the patch subject to reflect this ? Thanks, Mathieu > [ARCHTYPE="unknown"] > ) > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Fri Nov 9 12:41:28 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 9 Nov 2012 12:41:28 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Add libc errno translation layer to UST error code Message-ID: <1352482888-31077-1-git-send-email-dgoulet@efficios.com> Also add four new possible code being EEXIST, EINVAL, ENOSYS and EPERM. Signed-off-by: David Goulet --- include/lttng/ust-error.h | 6 +++++- liblttng-ust/lttng-ust-comm.c | 26 +++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/include/lttng/ust-error.h b/include/lttng/ust-error.h index 49890a9..241d554 100644 --- a/include/lttng/ust-error.h +++ b/include/lttng/ust-error.h @@ -36,7 +36,11 @@ enum lttng_ust_error_code { LTTNG_UST_OK = 0, /* Ok */ LTTNG_UST_ERR = 1024, /* Unknown Error */ - LTTNG_UST_ERR_NOENT, /* No entry */ + LTTNG_UST_ERR_NOENT = 1025, /* No entry */ + LTTNG_UST_ERR_EXIST = 1026, /* Object exists */ + LTTNG_UST_ERR_INVAL = 1027, /* Invalid argument */ + LTTNG_UST_ERR_PERM = 1028, /* Permission denied */ + LTTNG_UST_ERR_NOSYS = 1029, /* Not implemented */ /* MUST be last element */ LTTNG_UST_ERR_NR, /* Last element */ diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index f11b7d0..6eec73c 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -376,9 +376,29 @@ end: * we already have a more precise error message to * report. */ - if (ret > -LTTNG_UST_ERR) - lur.ret_code = -LTTNG_UST_ERR; - else + if (ret > -LTTNG_UST_ERR) { + /* Translate code to UST error. */ + switch (ret) { + case -EEXIST: + lur.ret_code = -LTTNG_UST_ERR_EXIST; + break; + case -EINVAL: + lur.ret_code = -LTTNG_UST_ERR_INVAL; + break; + case -ENOENT: + lur.ret_code = -LTTNG_UST_ERR_NOENT; + break; + case -EPERM: + lur.ret_code = -LTTNG_UST_ERR_PERM; + break; + case -ENOSYS: + lur.ret_code = -LTTNG_UST_ERR_NOSYS; + break; + default: + lur.ret_code = -LTTNG_UST_ERR; + break; + } + } else lur.ret_code = ret; } if (ret >= 0) { -- 1.7.10.4 From mathieu.desnoyers at efficios.com Fri Nov 9 13:11:43 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 9 Nov 2012 13:11:43 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Add libc errno translation layer to UST error code In-Reply-To: <1352482888-31077-1-git-send-email-dgoulet@efficios.com> References: <1352482888-31077-1-git-send-email-dgoulet@efficios.com> Message-ID: <20121109181143.GC19849@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Also add four new possible code being EEXIST, EINVAL, ENOSYS and EPERM. > > Signed-off-by: David Goulet > --- > include/lttng/ust-error.h | 6 +++++- > liblttng-ust/lttng-ust-comm.c | 26 +++++++++++++++++++++++--- > 2 files changed, 28 insertions(+), 4 deletions(-) > > diff --git a/include/lttng/ust-error.h b/include/lttng/ust-error.h > index 49890a9..241d554 100644 > --- a/include/lttng/ust-error.h > +++ b/include/lttng/ust-error.h > @@ -36,7 +36,11 @@ > enum lttng_ust_error_code { > LTTNG_UST_OK = 0, /* Ok */ > LTTNG_UST_ERR = 1024, /* Unknown Error */ > - LTTNG_UST_ERR_NOENT, /* No entry */ > + LTTNG_UST_ERR_NOENT = 1025, /* No entry */ > + LTTNG_UST_ERR_EXIST = 1026, /* Object exists */ > + LTTNG_UST_ERR_INVAL = 1027, /* Invalid argument */ > + LTTNG_UST_ERR_PERM = 1028, /* Permission denied */ > + LTTNG_UST_ERR_NOSYS = 1029, /* Not implemented */ you forgot the liblttng-ust-comm/liblttng-ust-comm.c array (mapping from values to strings). Thanks, Mathieu > > /* MUST be last element */ > LTTNG_UST_ERR_NR, /* Last element */ > diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c > index f11b7d0..6eec73c 100644 > --- a/liblttng-ust/lttng-ust-comm.c > +++ b/liblttng-ust/lttng-ust-comm.c > @@ -376,9 +376,29 @@ end: > * we already have a more precise error message to > * report. > */ > - if (ret > -LTTNG_UST_ERR) > - lur.ret_code = -LTTNG_UST_ERR; > - else > + if (ret > -LTTNG_UST_ERR) { > + /* Translate code to UST error. */ > + switch (ret) { > + case -EEXIST: > + lur.ret_code = -LTTNG_UST_ERR_EXIST; > + break; > + case -EINVAL: > + lur.ret_code = -LTTNG_UST_ERR_INVAL; > + break; > + case -ENOENT: > + lur.ret_code = -LTTNG_UST_ERR_NOENT; > + break; > + case -EPERM: > + lur.ret_code = -LTTNG_UST_ERR_PERM; > + break; > + case -ENOSYS: > + lur.ret_code = -LTTNG_UST_ERR_NOSYS; > + break; > + default: > + lur.ret_code = -LTTNG_UST_ERR; > + break; > + } > + } else > lur.ret_code = ret; > } > if (ret >= 0) { > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Fri Nov 9 13:16:18 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 9 Nov 2012 13:16:18 -0500 Subject: [lttng-dev] [PATCH lttng-ust v2] Add libc errno translation layer to UST error code Message-ID: <1352484978-19518-1-git-send-email-dgoulet@efficios.com> Also add four new possible code being EEXIST, EINVAL, ENOSYS and EPERM. Signed-off-by: David Goulet --- include/lttng/ust-error.h | 6 +++++- liblttng-ust-comm/lttng-ust-comm.c | 4 ++++ liblttng-ust/lttng-ust-comm.c | 26 +++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/include/lttng/ust-error.h b/include/lttng/ust-error.h index 49890a9..0d829f8 100644 --- a/include/lttng/ust-error.h +++ b/include/lttng/ust-error.h @@ -36,7 +36,11 @@ enum lttng_ust_error_code { LTTNG_UST_OK = 0, /* Ok */ LTTNG_UST_ERR = 1024, /* Unknown Error */ - LTTNG_UST_ERR_NOENT, /* No entry */ + LTTNG_UST_ERR_NOENT = 1025, /* No entry */ + LTTNG_UST_ERR_EXIST = 1026, /* Object exists */ + LTTNG_UST_ERR_INVAL = 1027, /* Invalid argument */ + LTTNG_UST_ERR_PERM = 1028, /* Permission denied */ + LTTNG_UST_ERR_NOSYS = 1029, /* Not implemented */ /* MUST be last element */ LTTNG_UST_ERR_NR, /* Last element */ diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c index 8765ea6..9a67ea1 100644 --- a/liblttng-ust-comm/lttng-ust-comm.c +++ b/liblttng-ust-comm/lttng-ust-comm.c @@ -44,6 +44,10 @@ static const char *ustcomm_readable_code[] = { [ USTCOMM_CODE_OFFSET(LTTNG_UST_OK) ] = "Success", [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR) ] = "Unknown error", [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOENT) ] = "No entry", + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXIST) ] = "Object already exists", + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL) ] = "Invalid argument", + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PERM) ] = "Permission denied", + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOSYS) ] = "Not implemented", }; /* diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c index f11b7d0..6eec73c 100644 --- a/liblttng-ust/lttng-ust-comm.c +++ b/liblttng-ust/lttng-ust-comm.c @@ -376,9 +376,29 @@ end: * we already have a more precise error message to * report. */ - if (ret > -LTTNG_UST_ERR) - lur.ret_code = -LTTNG_UST_ERR; - else + if (ret > -LTTNG_UST_ERR) { + /* Translate code to UST error. */ + switch (ret) { + case -EEXIST: + lur.ret_code = -LTTNG_UST_ERR_EXIST; + break; + case -EINVAL: + lur.ret_code = -LTTNG_UST_ERR_INVAL; + break; + case -ENOENT: + lur.ret_code = -LTTNG_UST_ERR_NOENT; + break; + case -EPERM: + lur.ret_code = -LTTNG_UST_ERR_PERM; + break; + case -ENOSYS: + lur.ret_code = -LTTNG_UST_ERR_NOSYS; + break; + default: + lur.ret_code = -LTTNG_UST_ERR; + break; + } + } else lur.ret_code = ret; } if (ret >= 0) { -- 1.7.10.4 From mathieu.desnoyers at efficios.com Fri Nov 9 13:21:45 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 9 Nov 2012 13:21:45 -0500 Subject: [lttng-dev] [PATCH lttng-ust v2] Add libc errno translation layer to UST error code In-Reply-To: <1352484978-19518-1-git-send-email-dgoulet@efficios.com> References: <1352484978-19518-1-git-send-email-dgoulet@efficios.com> Message-ID: <20121109182145.GA23712@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Also add four new possible code being EEXIST, EINVAL, ENOSYS and EPERM. merged with minor style changes, Thanks, Mathieu > > Signed-off-by: David Goulet > --- > include/lttng/ust-error.h | 6 +++++- > liblttng-ust-comm/lttng-ust-comm.c | 4 ++++ > liblttng-ust/lttng-ust-comm.c | 26 +++++++++++++++++++++++--- > 3 files changed, 32 insertions(+), 4 deletions(-) > > diff --git a/include/lttng/ust-error.h b/include/lttng/ust-error.h > index 49890a9..0d829f8 100644 > --- a/include/lttng/ust-error.h > +++ b/include/lttng/ust-error.h > @@ -36,7 +36,11 @@ > enum lttng_ust_error_code { > LTTNG_UST_OK = 0, /* Ok */ > LTTNG_UST_ERR = 1024, /* Unknown Error */ > - LTTNG_UST_ERR_NOENT, /* No entry */ > + LTTNG_UST_ERR_NOENT = 1025, /* No entry */ > + LTTNG_UST_ERR_EXIST = 1026, /* Object exists */ > + LTTNG_UST_ERR_INVAL = 1027, /* Invalid argument */ > + LTTNG_UST_ERR_PERM = 1028, /* Permission denied */ > + LTTNG_UST_ERR_NOSYS = 1029, /* Not implemented */ > > /* MUST be last element */ > LTTNG_UST_ERR_NR, /* Last element */ > diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c > index 8765ea6..9a67ea1 100644 > --- a/liblttng-ust-comm/lttng-ust-comm.c > +++ b/liblttng-ust-comm/lttng-ust-comm.c > @@ -44,6 +44,10 @@ static const char *ustcomm_readable_code[] = { > [ USTCOMM_CODE_OFFSET(LTTNG_UST_OK) ] = "Success", > [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR) ] = "Unknown error", > [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOENT) ] = "No entry", > + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXIST) ] = "Object already exists", > + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL) ] = "Invalid argument", > + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PERM) ] = "Permission denied", > + [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOSYS) ] = "Not implemented", > }; > > /* > diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c > index f11b7d0..6eec73c 100644 > --- a/liblttng-ust/lttng-ust-comm.c > +++ b/liblttng-ust/lttng-ust-comm.c > @@ -376,9 +376,29 @@ end: > * we already have a more precise error message to > * report. > */ > - if (ret > -LTTNG_UST_ERR) > - lur.ret_code = -LTTNG_UST_ERR; > - else > + if (ret > -LTTNG_UST_ERR) { > + /* Translate code to UST error. */ > + switch (ret) { > + case -EEXIST: > + lur.ret_code = -LTTNG_UST_ERR_EXIST; > + break; > + case -EINVAL: > + lur.ret_code = -LTTNG_UST_ERR_INVAL; > + break; > + case -ENOENT: > + lur.ret_code = -LTTNG_UST_ERR_NOENT; > + break; > + case -EPERM: > + lur.ret_code = -LTTNG_UST_ERR_PERM; > + break; > + case -ENOSYS: > + lur.ret_code = -LTTNG_UST_ERR_NOSYS; > + break; > + default: > + lur.ret_code = -LTTNG_UST_ERR; > + break; > + } > + } else > lur.ret_code = ret; > } > if (ret >= 0) { > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From miloody at gmail.com Sat Nov 10 04:55:57 2012 From: miloody at gmail.com (loody) Date: Sat, 10 Nov 2012 17:55:57 +0800 Subject: [lttng-dev] some questions about lttng Message-ID: hi all: each time I use lttng, I -- Regards, From simon.marchi at polymtl.ca Sun Nov 11 23:28:33 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Sun, 11 Nov 2012 23:28:33 -0500 Subject: [lttng-dev] [PATCH 1/2] Add default subbuf sizes getter functions Message-ID: <1352694514-25027-1-git-send-email-simon.marchi@polymtl.ca> This patch adds src/common/defaults.c file. It contains functions to retrieve defaults subbuf sizes. It uses the DEFAULT_*_SUBBUF_SIZE defines from defaults.h but also make sure that the values are at least as big as the page size. Signed-off-by: Simon Marchi --- src/common/Makefile.am | 2 +- src/common/defaults.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ src/common/defaults.h | 7 ++++ 3 files changed, 99 insertions(+), 1 deletions(-) create mode 100644 src/common/defaults.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b43b376..f91259c 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ - common.h futex.c futex.h uri.c uri.h + common.h futex.c futex.h uri.c uri.h defaults.c # Consumer library noinst_LTLIBRARIES += libconsumer.la diff --git a/src/common/defaults.c b/src/common/defaults.c new file mode 100644 index 0000000..cde4fb9 --- /dev/null +++ b/src/common/defaults.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 - Simon Marchi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "defaults.h" + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +static size_t default_channel_subbuf_size; +static size_t default_metadata_subbuf_size; +static size_t default_kernel_channel_subbuf_size; +static size_t default_ust_channel_subbuf_size; + +static void __attribute__((constructor)) init_defaults(void) +{ + /* libringbuffer won't accept subbuf sizes smaller than the page size, + * so. If the default subbuf size is smaller, replace it by the page + * size. */ + long page_size = sysconf(_SC_PAGESIZE); + + if (page_size < 0) { + page_size = 0; + } + + default_channel_subbuf_size = max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); + default_metadata_subbuf_size = max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); + default_kernel_channel_subbuf_size = max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); + default_ust_channel_subbuf_size = max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); +} + +/* + * Returns the default subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t default_get_channel_subbuf_size(void) +{ + return default_channel_subbuf_size; +} + +/* + * Returns the default metadata subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t default_get_metadata_subbuf_size(void) +{ + return default_metadata_subbuf_size; +} + +/* + * Returns the default subbuf size for the kernel domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t default_get_kernel_channel_subbuf_size(void) +{ + return default_kernel_channel_subbuf_size; +} + +/* + * Returns the default subbuf size for the UST domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +size_t default_get_ust_channel_subbuf_size(void) +{ + return default_ust_channel_subbuf_size; +} diff --git a/src/common/defaults.h b/src/common/defaults.h index 0c0b6ac..94a54c1 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -109,6 +109,9 @@ #define DEFAULT_METADATA_SUBBUF_SIZE 4096 #define DEFAULT_METADATA_SUBBUF_NUM 2 +size_t default_get_channel_subbuf_size(void); +size_t default_get_metadata_subbuf_size(void); + /* Kernel has different defaults */ /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ @@ -121,6 +124,8 @@ /* See lttng-kernel.h enum lttng_kernel_output for channel output */ #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE +size_t default_get_kernel_channel_subbuf_size(void); + /* User space defaults */ /* Must be a power of 2 */ @@ -130,6 +135,8 @@ /* See lttng-ust.h enum lttng_ust_output */ #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP +size_t default_get_ust_channel_subbuf_size(void); + /* * Default timeout value for the sem_timedwait() call. Blocking forever is not * wanted so a timeout is used to control the data flow and not freeze the -- 1.7.1 From simon.marchi at polymtl.ca Sun Nov 11 23:28:34 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Sun, 11 Nov 2012 23:28:34 -0500 Subject: [lttng-dev] [PATCH 2/2] Use the new functions for default subbuf sizes. In-Reply-To: <1352694514-25027-1-git-send-email-simon.marchi@polymtl.ca> References: <1352694514-25027-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352694514-25027-2-git-send-email-simon.marchi@polymtl.ca> Use the functions added by the previous commit. All the occurences of the previous defines were replaced. Signed-off-by: Simon Marchi --- src/bin/lttng-sessiond/channel.c | 4 ++-- src/bin/lttng-sessiond/trace-kernel.c | 2 +- src/bin/lttng-sessiond/trace-ust.c | 2 +- src/bin/lttng/commands/enable_channels.c | 6 +++--- src/lib/lttng-ctl/lttng-ctl.c | 4 ++-- tests/tools/Makefile.am | 2 +- tests/tools/test_kernel_data_trace.c | 2 +- tests/tools/test_ust_data_trace.c | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 8b9adfb..a942ff5 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -54,7 +54,7 @@ struct lttng_channel *channel_new_default_attr(int dom) switch (dom) { case LTTNG_DOMAIN_KERNEL: - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_kernel_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -64,7 +64,7 @@ struct lttng_channel *channel_new_default_attr(int dom) case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: case LTTNG_DOMAIN_UST_EXEC_NAME: #endif - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_ust_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 7748b89..4d2870a 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -272,7 +272,7 @@ struct ltt_kernel_metadata *trace_kernel_create_metadata(void) /* Set default attributes */ chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_metadata_subbuf_size(); chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 864a4b0..2dcc7c2 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -311,7 +311,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) /* Set default attributes */ lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + lum->attr.subbuf_size = default_get_metadata_subbuf_size(); lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 1857477..d9a3b02 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -101,9 +101,9 @@ static void usage(FILE *ofp) fprintf(ofp, " --overwrite Flight recorder mode%s\n", DEFAULT_CHANNEL_OVERWRITE ? " (default)" : ""); fprintf(ofp, " --subbuf-size SIZE Subbuffer size in bytes\n"); - fprintf(ofp, " (default: %u, kernel default: %u)\n", - DEFAULT_CHANNEL_SUBBUF_SIZE, - DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); + fprintf(ofp, " (default: %zu, kernel default: %zu)\n", + default_get_channel_subbuf_size(), + default_get_kernel_channel_subbuf_size()); fprintf(ofp, " Needs to be a power of 2 for\n"); fprintf(ofp, " kernel and ust tracers\n"); fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 46338fb..20bb8c6 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1344,7 +1344,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_kernel_channel_subbuf_size(); attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -1358,7 +1358,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_ust_channel_subbuf_size(); attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am index cd7ff32..4fe494c 100644 --- a/tests/tools/Makefile.am +++ b/tests/tools/Makefile.am @@ -27,7 +27,7 @@ test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM) # Kernel trace data unit tests test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE) -test_kernel_data_trace_LDADD = $(SESSIOND_COMM) $(HASHTABLE) +test_kernel_data_trace_LDADD = $(COMMON) $(SESSIOND_COMM) $(HASHTABLE) if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += test_ust_data_trace diff --git a/tests/tools/test_kernel_data_trace.c b/tests/tools/test_kernel_data_trace.c index c49d7ce..1edd20d 100644 --- a/tests/tools/test_kernel_data_trace.c +++ b/tests/tools/test_kernel_data_trace.c @@ -99,7 +99,7 @@ static void create_kernel_metadata(void) assert(kern->metadata->conf->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(kern->metadata->conf->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(kern->metadata->conf->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(kern->metadata->conf->attr.switch_timer_interval diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c index 459520d..69a73b2 100644 --- a/tests/tools/test_ust_data_trace.c +++ b/tests/tools/test_ust_data_trace.c @@ -107,7 +107,7 @@ static void create_ust_metadata(void) assert(metadata->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(metadata->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(metadata->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(metadata->attr.switch_timer_interval -- 1.7.1 From simon.marchi at polymtl.ca Sun Nov 11 23:36:03 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Sun, 11 Nov 2012 20:36:03 -0800 Subject: [lttng-dev] [PATCH 1/3] Add default subbuf sizes getter functions. In-Reply-To: <509D26D3.4070609@efficios.com> References: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> <509D26D3.4070609@efficios.com> Message-ID: Hi David, I just sent my v2 for this patch. I changed the logic so that it still uses the DEFAULT_*_SUBBUF_SIZE defines, but check that it is >= page size. It should answer your first two comments/questions. I don't think it would help to put these inline, since they are only called in slow paths. Simon > Hi Simon, > > Can you please rename the get_default_* function family to default_get_* > in order to respect the name spacing of files. > > Comment below: > > Simon Marchi: >> This patch adds src/common/defaults.c file. It contains functions to >> retrieve defaults subbuf sizes based on the architecture page size. >> >> Signed-off-by: Simon Marchi >> --- >> src/common/Makefile.am | 2 +- >> src/common/defaults.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ >> src/common/defaults.h | 7 ++++ >> 3 files changed, 94 insertions(+), 1 deletions(-) >> create mode 100644 src/common/defaults.c >> >> diff --git a/src/common/Makefile.am b/src/common/Makefile.am >> index b43b376..f91259c 100644 >> --- a/src/common/Makefile.am >> +++ b/src/common/Makefile.am >> @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ >> noinst_LTLIBRARIES = libcommon.la >> >> libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ >> - common.h futex.c futex.h uri.c uri.h >> + common.h futex.c futex.h uri.c uri.h defaults.c >> >> # Consumer library >> noinst_LTLIBRARIES += libconsumer.la >> diff --git a/src/common/defaults.c b/src/common/defaults.c >> new file mode 100644 >> index 0000000..48d6605 >> --- /dev/null >> +++ b/src/common/defaults.c >> @@ -0,0 +1,86 @@ >> +/* >> + * Copyright (C) 2012 - Simon Marchi >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License, version 2 only, >> + * as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, but WITHOUT >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for >> + * more details. >> + * >> + * You should have received a copy of the GNU General Public License along >> + * with this program; if not, write to the Free Software Foundation, Inc., >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >> + */ >> + >> +#include >> +#include >> + >> +#include "defaults.h" >> + >> +static size_t default_channel_subbuf_size; >> +static size_t default_metadata_subbuf_size; >> +static size_t default_kernel_channel_subbuf_size; >> +static size_t default_ust_channel_subbuf_size; >> + >> +static void __attribute__((constructor)) init_defaults(void) >> +{ >> + default_kernel_channel_subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; > > Why is the kernel getting a default value and not a page size ? > >> + >> + long page_size = sysconf(_SC_PAGESIZE); >> + if (page_size > 0) { >> + default_channel_subbuf_size = page_size; >> + default_metadata_subbuf_size = page_size; >> + default_ust_channel_subbuf_size = page_size; >> + } else { >> + default_channel_subbuf_size = 4096; >> + default_metadata_subbuf_size = 4096; >> + default_ust_channel_subbuf_size = 4096; > > Should we use a default value for this 4096 size here with a > DEFINE_*_SUBBUF_SIZE or... ? > > Seems a bit odd that the kernel got a default define value but not UST > and metadata. > >> + } >> +} >> + >> +/* >> + * Returns the default subbuf size. >> + * >> + * This function depends on a value that is set at constructor time, so it is >> + * unsafe to call it from another constructor. >> + */ >> +size_t get_default_channel_subbuf_size(void) >> +{ >> + return default_channel_subbuf_size; >> +} >> + >> +/* >> + * Returns the default metadata subbuf size. >> + * >> + * This function depends on a value that is set at constructor time, so it is >> + * unsafe to call it from another constructor. >> + */ >> +size_t get_default_metadata_subbuf_size(void) >> +{ >> + return default_metadata_subbuf_size; >> +} >> + >> +/* >> + * Returns the default subbuf size for the kernel domain. >> + * >> + * This function depends on a value that is set at constructor time, so it is >> + * unsafe to call it from another constructor. >> + */ >> +size_t get_default_kernel_channel_subbuf_size(void) >> +{ >> + return default_kernel_channel_subbuf_size; >> +} >> + >> +/* >> + * Returns the default subbuf size for the UST domain. >> + * >> + * This function depends on a value that is set at constructor time, so it is >> + * unsafe to call it from another constructor. >> + */ >> +size_t get_default_ust_channel_subbuf_size(void) >> +{ >> + return default_ust_channel_subbuf_size; >> +} > > I'm wondering if all these functions should be static inline in the > default.h... > > Thoughts? > > Otherwise, the patch looks good! > > Thanks > David > >> diff --git a/src/common/defaults.h b/src/common/defaults.h >> index 0c0b6ac..efff43e 100644 >> --- a/src/common/defaults.h >> +++ b/src/common/defaults.h >> @@ -109,6 +109,9 @@ >> #define DEFAULT_METADATA_SUBBUF_SIZE 4096 >> #define DEFAULT_METADATA_SUBBUF_NUM 2 >> >> +size_t get_default_channel_subbuf_size(void); >> +size_t get_default_metadata_subbuf_size(void); >> + >> /* Kernel has different defaults */ >> >> /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ >> @@ -121,6 +124,8 @@ >> /* See lttng-kernel.h enum lttng_kernel_output for channel output */ >> #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE >> >> +size_t get_default_kernel_channel_subbuf_size(void); >> + >> /* User space defaults */ >> >> /* Must be a power of 2 */ >> @@ -130,6 +135,8 @@ >> /* See lttng-ust.h enum lttng_ust_output */ >> #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP >> >> +size_t get_default_ust_channel_subbuf_size(void); >> + >> /* >> * Default timeout value for the sem_timedwait() call. Blocking forever is not >> * wanted so a timeout is used to control the data flow and not freeze the > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From simon.marchi at polymtl.ca Sun Nov 11 23:36:33 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Sun, 11 Nov 2012 20:36:33 -0800 Subject: [lttng-dev] [PATCH 2/2] Use the new functions for default subbuf sizes. In-Reply-To: <1352694514-25027-2-git-send-email-simon.marchi@polymtl.ca> References: <1352694514-25027-1-git-send-email-simon.marchi@polymtl.ca> <1352694514-25027-2-git-send-email-simon.marchi@polymtl.ca> Message-ID: Forgot to remove the dot at the end of the title... On Sun, Nov 11, 2012 at 8:28 PM, Simon Marchi wrote: > Use the functions added by the previous commit. All the occurences of > the previous defines were replaced. > > Signed-off-by: Simon Marchi > --- > src/bin/lttng-sessiond/channel.c | 4 ++-- > src/bin/lttng-sessiond/trace-kernel.c | 2 +- > src/bin/lttng-sessiond/trace-ust.c | 2 +- > src/bin/lttng/commands/enable_channels.c | 6 +++--- > src/lib/lttng-ctl/lttng-ctl.c | 4 ++-- > tests/tools/Makefile.am | 2 +- > tests/tools/test_kernel_data_trace.c | 2 +- > tests/tools/test_ust_data_trace.c | 2 +- > 8 files changed, 12 insertions(+), 12 deletions(-) > > diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c > index 8b9adfb..a942ff5 100644 > --- a/src/bin/lttng-sessiond/channel.c > +++ b/src/bin/lttng-sessiond/channel.c > @@ -54,7 +54,7 @@ struct lttng_channel *channel_new_default_attr(int dom) > > switch (dom) { > case LTTNG_DOMAIN_KERNEL: > - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; > + chan->attr.subbuf_size = default_get_kernel_channel_subbuf_size(); > chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; > chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; > break; > @@ -64,7 +64,7 @@ struct lttng_channel *channel_new_default_attr(int dom) > case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: > case LTTNG_DOMAIN_UST_EXEC_NAME: > #endif > - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; > + chan->attr.subbuf_size = default_get_ust_channel_subbuf_size(); > chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; > chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; > break; > diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c > index 7748b89..4d2870a 100644 > --- a/src/bin/lttng-sessiond/trace-kernel.c > +++ b/src/bin/lttng-sessiond/trace-kernel.c > @@ -272,7 +272,7 @@ struct ltt_kernel_metadata *trace_kernel_create_metadata(void) > > /* Set default attributes */ > chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; > - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; > + chan->attr.subbuf_size = default_get_metadata_subbuf_size(); > chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; > chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; > chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; > diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c > index 864a4b0..2dcc7c2 100644 > --- a/src/bin/lttng-sessiond/trace-ust.c > +++ b/src/bin/lttng-sessiond/trace-ust.c > @@ -311,7 +311,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) > > /* Set default attributes */ > lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; > - lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; > + lum->attr.subbuf_size = default_get_metadata_subbuf_size(); > lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; > lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; > lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; > diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c > index 1857477..d9a3b02 100644 > --- a/src/bin/lttng/commands/enable_channels.c > +++ b/src/bin/lttng/commands/enable_channels.c > @@ -101,9 +101,9 @@ static void usage(FILE *ofp) > fprintf(ofp, " --overwrite Flight recorder mode%s\n", > DEFAULT_CHANNEL_OVERWRITE ? " (default)" : ""); > fprintf(ofp, " --subbuf-size SIZE Subbuffer size in bytes\n"); > - fprintf(ofp, " (default: %u, kernel default: %u)\n", > - DEFAULT_CHANNEL_SUBBUF_SIZE, > - DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); > + fprintf(ofp, " (default: %zu, kernel default: %zu)\n", > + default_get_channel_subbuf_size(), > + default_get_kernel_channel_subbuf_size()); > fprintf(ofp, " Needs to be a power of 2 for\n"); > fprintf(ofp, " kernel and ust tracers\n"); > fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); > diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c > index 46338fb..20bb8c6 100644 > --- a/src/lib/lttng-ctl/lttng-ctl.c > +++ b/src/lib/lttng-ctl/lttng-ctl.c > @@ -1344,7 +1344,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, > attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; > attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; > > - attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; > + attr->subbuf_size = default_get_kernel_channel_subbuf_size(); > attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; > attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT; > break; > @@ -1358,7 +1358,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, > attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; > attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; > > - attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; > + attr->subbuf_size = default_get_ust_channel_subbuf_size(); > attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; > attr->output = DEFAULT_UST_CHANNEL_OUTPUT; > break; > diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am > index cd7ff32..4fe494c 100644 > --- a/tests/tools/Makefile.am > +++ b/tests/tools/Makefile.am > @@ -27,7 +27,7 @@ test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM) > > # Kernel trace data unit tests > test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE) > -test_kernel_data_trace_LDADD = $(SESSIOND_COMM) $(HASHTABLE) > +test_kernel_data_trace_LDADD = $(COMMON) $(SESSIOND_COMM) $(HASHTABLE) > > if HAVE_LIBLTTNG_UST_CTL > noinst_PROGRAMS += test_ust_data_trace > diff --git a/tests/tools/test_kernel_data_trace.c b/tests/tools/test_kernel_data_trace.c > index c49d7ce..1edd20d 100644 > --- a/tests/tools/test_kernel_data_trace.c > +++ b/tests/tools/test_kernel_data_trace.c > @@ -99,7 +99,7 @@ static void create_kernel_metadata(void) > assert(kern->metadata->conf->attr.overwrite > == DEFAULT_CHANNEL_OVERWRITE); > assert(kern->metadata->conf->attr.subbuf_size > - == DEFAULT_METADATA_SUBBUF_SIZE); > + == default_get_metadata_subbuf_size()); > assert(kern->metadata->conf->attr.num_subbuf > == DEFAULT_METADATA_SUBBUF_NUM); > assert(kern->metadata->conf->attr.switch_timer_interval > diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c > index 459520d..69a73b2 100644 > --- a/tests/tools/test_ust_data_trace.c > +++ b/tests/tools/test_ust_data_trace.c > @@ -107,7 +107,7 @@ static void create_ust_metadata(void) > assert(metadata->attr.overwrite > == DEFAULT_CHANNEL_OVERWRITE); > assert(metadata->attr.subbuf_size > - == DEFAULT_METADATA_SUBBUF_SIZE); > + == default_get_metadata_subbuf_size()); > assert(metadata->attr.num_subbuf > == DEFAULT_METADATA_SUBBUF_NUM); > assert(metadata->attr.switch_timer_interval > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From mathieu.desnoyers at efficios.com Sun Nov 11 23:54:32 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 11 Nov 2012 23:54:32 -0500 Subject: [lttng-dev] [PATCH 1/3] Add default subbuf sizes getter functions. In-Reply-To: References: <1352443148-7135-1-git-send-email-simon.marchi@polymtl.ca> <509D26D3.4070609@efficios.com> Message-ID: <20121112045432.GA20210@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Hi David, > > I just sent my v2 for this patch. I changed the logic so that it still > uses the DEFAULT_*_SUBBUF_SIZE defines, but check that it is >= page > size. It should answer your first two comments/questions. > > I don't think it would help to put these inline, since they are only > called in slow paths. Even though those are slow paths, adding a symbol and function call just to fetch a variable seems overkill. I agree with David: those should be made static inline. Thanks, Mathieu > > Simon > > > Hi Simon, > > > > Can you please rename the get_default_* function family to default_get_* > > in order to respect the name spacing of files. > > > > Comment below: > > > > Simon Marchi: > >> This patch adds src/common/defaults.c file. It contains functions to > >> retrieve defaults subbuf sizes based on the architecture page size. > >> > >> Signed-off-by: Simon Marchi > >> --- > >> src/common/Makefile.am | 2 +- > >> src/common/defaults.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ > >> src/common/defaults.h | 7 ++++ > >> 3 files changed, 94 insertions(+), 1 deletions(-) > >> create mode 100644 src/common/defaults.c > >> > >> diff --git a/src/common/Makefile.am b/src/common/Makefile.am > >> index b43b376..f91259c 100644 > >> --- a/src/common/Makefile.am > >> +++ b/src/common/Makefile.am > >> @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ > >> noinst_LTLIBRARIES = libcommon.la > >> > >> libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ > >> - common.h futex.c futex.h uri.c uri.h > >> + common.h futex.c futex.h uri.c uri.h defaults.c > >> > >> # Consumer library > >> noinst_LTLIBRARIES += libconsumer.la > >> diff --git a/src/common/defaults.c b/src/common/defaults.c > >> new file mode 100644 > >> index 0000000..48d6605 > >> --- /dev/null > >> +++ b/src/common/defaults.c > >> @@ -0,0 +1,86 @@ > >> +/* > >> + * Copyright (C) 2012 - Simon Marchi > >> + * > >> + * This program is free software; you can redistribute it and/or modify > >> + * it under the terms of the GNU General Public License, version 2 only, > >> + * as published by the Free Software Foundation. > >> + * > >> + * This program is distributed in the hope that it will be useful, but WITHOUT > >> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > >> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > >> + * more details. > >> + * > >> + * You should have received a copy of the GNU General Public License along > >> + * with this program; if not, write to the Free Software Foundation, Inc., > >> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > >> + */ > >> + > >> +#include > >> +#include > >> + > >> +#include "defaults.h" > >> + > >> +static size_t default_channel_subbuf_size; > >> +static size_t default_metadata_subbuf_size; > >> +static size_t default_kernel_channel_subbuf_size; > >> +static size_t default_ust_channel_subbuf_size; > >> + > >> +static void __attribute__((constructor)) init_defaults(void) > >> +{ > >> + default_kernel_channel_subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; > > > > Why is the kernel getting a default value and not a page size ? > > > >> + > >> + long page_size = sysconf(_SC_PAGESIZE); > >> + if (page_size > 0) { > >> + default_channel_subbuf_size = page_size; > >> + default_metadata_subbuf_size = page_size; > >> + default_ust_channel_subbuf_size = page_size; > >> + } else { > >> + default_channel_subbuf_size = 4096; > >> + default_metadata_subbuf_size = 4096; > >> + default_ust_channel_subbuf_size = 4096; > > > > Should we use a default value for this 4096 size here with a > > DEFINE_*_SUBBUF_SIZE or... ? > > > > Seems a bit odd that the kernel got a default define value but not UST > > and metadata. > > > >> + } > >> +} > >> + > >> +/* > >> + * Returns the default subbuf size. > >> + * > >> + * This function depends on a value that is set at constructor time, so it is > >> + * unsafe to call it from another constructor. > >> + */ > >> +size_t get_default_channel_subbuf_size(void) > >> +{ > >> + return default_channel_subbuf_size; > >> +} > >> + > >> +/* > >> + * Returns the default metadata subbuf size. > >> + * > >> + * This function depends on a value that is set at constructor time, so it is > >> + * unsafe to call it from another constructor. > >> + */ > >> +size_t get_default_metadata_subbuf_size(void) > >> +{ > >> + return default_metadata_subbuf_size; > >> +} > >> + > >> +/* > >> + * Returns the default subbuf size for the kernel domain. > >> + * > >> + * This function depends on a value that is set at constructor time, so it is > >> + * unsafe to call it from another constructor. > >> + */ > >> +size_t get_default_kernel_channel_subbuf_size(void) > >> +{ > >> + return default_kernel_channel_subbuf_size; > >> +} > >> + > >> +/* > >> + * Returns the default subbuf size for the UST domain. > >> + * > >> + * This function depends on a value that is set at constructor time, so it is > >> + * unsafe to call it from another constructor. > >> + */ > >> +size_t get_default_ust_channel_subbuf_size(void) > >> +{ > >> + return default_ust_channel_subbuf_size; > >> +} > > > > I'm wondering if all these functions should be static inline in the > > default.h... > > > > Thoughts? > > > > Otherwise, the patch looks good! > > > > Thanks > > David > > > >> diff --git a/src/common/defaults.h b/src/common/defaults.h > >> index 0c0b6ac..efff43e 100644 > >> --- a/src/common/defaults.h > >> +++ b/src/common/defaults.h > >> @@ -109,6 +109,9 @@ > >> #define DEFAULT_METADATA_SUBBUF_SIZE 4096 > >> #define DEFAULT_METADATA_SUBBUF_NUM 2 > >> > >> +size_t get_default_channel_subbuf_size(void); > >> +size_t get_default_metadata_subbuf_size(void); > >> + > >> /* Kernel has different defaults */ > >> > >> /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ > >> @@ -121,6 +124,8 @@ > >> /* See lttng-kernel.h enum lttng_kernel_output for channel output */ > >> #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE > >> > >> +size_t get_default_kernel_channel_subbuf_size(void); > >> + > >> /* User space defaults */ > >> > >> /* Must be a power of 2 */ > >> @@ -130,6 +135,8 @@ > >> /* See lttng-ust.h enum lttng_ust_output */ > >> #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP > >> > >> +size_t get_default_ust_channel_subbuf_size(void); > >> + > >> /* > >> * Default timeout value for the sem_timedwait() call. Blocking forever is not > >> * wanted so a timeout is used to control the data flow and not freeze the > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Mon Nov 12 08:36:40 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Mon, 12 Nov 2012 14:36:40 +0100 Subject: [lttng-dev] [PATCH lttng-modules] Additional kernel probes Message-ID: <50A0FB68.5060100@mentor.com> Hi Mathieu, we created a set of additional kernel probes for LTTng 2.0. The patch below adds asoc, ext3, gpio, jbd, jbd2, kmem, lock, module, napi, net, power, regulator, scsi, skb, sock, udp, vmscan probes to LTTng 2.0. The probes are verified to compile against all kernel versions from 3.0 to 3.6 (3.7-rc5 also works). >From 0f8a89285458f19c627c018d37891fafa9819fca Mon Sep 17 00:00:00 2001 From: Paul Woegerer Date: Mon, 12 Nov 2012 14:07:12 +0100 Subject: [PATCH] Add kernel probes for asoc, ext3, gpio, jbd, jbd2, kmem, lock, module, napi, net, power, regulator, scsi, skb, sock, udp, vmscan. --- instrumentation/events/lttng-module/asoc.h | 340 ++++++ instrumentation/events/lttng-module/ext3.h | 870 +++++++++++++++ instrumentation/events/lttng-module/gpio.h | 56 + instrumentation/events/lttng-module/jbd.h | 243 +++++ instrumentation/events/lttng-module/jbd2.h | 238 ++++ instrumentation/events/lttng-module/kmem.h | 304 ++++++ instrumentation/events/lttng-module/lock.h | 86 ++ instrumentation/events/lttng-module/module.h | 134 +++ instrumentation/events/lttng-module/napi.h | 38 + instrumentation/events/lttng-module/net.h | 84 ++ instrumentation/events/lttng-module/power.h | 240 ++++ instrumentation/events/lttng-module/regulator.h | 141 +++ instrumentation/events/lttng-module/scsi.h | 369 +++++++ instrumentation/events/lttng-module/skb.h | 75 ++ instrumentation/events/lttng-module/sock.h | 68 ++ instrumentation/events/lttng-module/udp.h | 32 + instrumentation/events/lttng-module/vmscan.h | 499 +++++++++ instrumentation/events/mainline/asoc.h | 330 ++++++ instrumentation/events/mainline/ext3.h | 864 +++++++++++++++ instrumentation/events/mainline/fs_ext3.h | 1323 +++++++++++++++++++++++ instrumentation/events/mainline/gpio.h | 56 + instrumentation/events/mainline/jbd.h | 203 ++++ instrumentation/events/mainline/jbd2.h | 235 ++++ instrumentation/events/mainline/kmem.h | 308 ++++++ instrumentation/events/mainline/lock.h | 86 ++ instrumentation/events/mainline/module.h | 131 +++ instrumentation/events/mainline/napi.h | 38 + instrumentation/events/mainline/net.h | 84 ++ instrumentation/events/mainline/power.h | 240 ++++ instrumentation/events/mainline/regulator.h | 141 +++ instrumentation/events/mainline/scsi.h | 365 +++++++ instrumentation/events/mainline/skb.h | 75 ++ instrumentation/events/mainline/sock.h | 68 ++ instrumentation/events/mainline/udp.h | 32 + instrumentation/events/mainline/vmscan.h | 477 ++++++++ probes/Makefile | 72 ++ probes/lttng-probe-asoc.c | 45 + probes/lttng-probe-ext3.c | 56 + probes/lttng-probe-gpio.c | 43 + probes/lttng-probe-jbd.c | 44 + probes/lttng-probe-jbd2.c | 43 + probes/lttng-probe-kmem.c | 43 + probes/lttng-probe-lock.c | 43 + probes/lttng-probe-module.c | 43 + probes/lttng-probe-napi.c | 43 + probes/lttng-probe-net.c | 43 + probes/lttng-probe-power.c | 43 + probes/lttng-probe-regulator.c | 43 + probes/lttng-probe-scsi.c | 44 + probes/lttng-probe-skb.c | 43 + probes/lttng-probe-sock.c | 43 + probes/lttng-probe-udp.c | 43 + probes/lttng-probe-vmscan.c | 48 + 53 files changed, 9698 insertions(+) create mode 100644 instrumentation/events/lttng-module/asoc.h create mode 100644 instrumentation/events/lttng-module/ext3.h create mode 100644 instrumentation/events/lttng-module/gpio.h create mode 100644 instrumentation/events/lttng-module/jbd.h create mode 100644 instrumentation/events/lttng-module/jbd2.h create mode 100644 instrumentation/events/lttng-module/kmem.h create mode 100644 instrumentation/events/lttng-module/lock.h create mode 100644 instrumentation/events/lttng-module/module.h create mode 100644 instrumentation/events/lttng-module/napi.h create mode 100644 instrumentation/events/lttng-module/net.h create mode 100644 instrumentation/events/lttng-module/power.h create mode 100644 instrumentation/events/lttng-module/regulator.h create mode 100644 instrumentation/events/lttng-module/scsi.h create mode 100644 instrumentation/events/lttng-module/skb.h create mode 100644 instrumentation/events/lttng-module/sock.h create mode 100644 instrumentation/events/lttng-module/udp.h create mode 100644 instrumentation/events/lttng-module/vmscan.h create mode 100644 instrumentation/events/mainline/asoc.h create mode 100644 instrumentation/events/mainline/ext3.h create mode 100644 instrumentation/events/mainline/fs_ext3.h create mode 100644 instrumentation/events/mainline/gpio.h create mode 100644 instrumentation/events/mainline/jbd.h create mode 100644 instrumentation/events/mainline/jbd2.h create mode 100644 instrumentation/events/mainline/kmem.h create mode 100644 instrumentation/events/mainline/lock.h create mode 100644 instrumentation/events/mainline/module.h create mode 100644 instrumentation/events/mainline/napi.h create mode 100644 instrumentation/events/mainline/net.h create mode 100644 instrumentation/events/mainline/power.h create mode 100644 instrumentation/events/mainline/regulator.h create mode 100644 instrumentation/events/mainline/scsi.h create mode 100644 instrumentation/events/mainline/skb.h create mode 100644 instrumentation/events/mainline/sock.h create mode 100644 instrumentation/events/mainline/udp.h create mode 100644 instrumentation/events/mainline/vmscan.h create mode 100644 probes/lttng-probe-asoc.c create mode 100644 probes/lttng-probe-ext3.c create mode 100644 probes/lttng-probe-gpio.c create mode 100644 probes/lttng-probe-jbd.c create mode 100644 probes/lttng-probe-jbd2.c create mode 100644 probes/lttng-probe-kmem.c create mode 100644 probes/lttng-probe-lock.c create mode 100644 probes/lttng-probe-module.c create mode 100644 probes/lttng-probe-napi.c create mode 100644 probes/lttng-probe-net.c create mode 100644 probes/lttng-probe-power.c create mode 100644 probes/lttng-probe-regulator.c create mode 100644 probes/lttng-probe-scsi.c create mode 100644 probes/lttng-probe-skb.c create mode 100644 probes/lttng-probe-sock.c create mode 100644 probes/lttng-probe-udp.c create mode 100644 probes/lttng-probe-vmscan.c diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h new file mode 100644 index 0000000..cb9e701 --- /dev/null +++ b/instrumentation/events/lttng-module/asoc.h @@ -0,0 +1,340 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM asoc + +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ASOC_H + +#include +#include +#include + +#ifndef _TRACE_ASOC_DEF +#define _TRACE_ASOC_DEF +struct snd_soc_jack; +struct snd_soc_codec; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) +struct snd_soc_platform; +#endif +struct snd_soc_card; +struct snd_soc_dapm_widget; +#endif + +/* + * Log register events + */ +DECLARE_EVENT_CLASS(snd_soc_reg, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val), + + TP_STRUCT__entry( + __string( name, codec->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, codec->name); + tp_assign(id, codec->id); + tp_assign(reg, reg); + tp_assign(val, val); + ), + + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +) + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +) + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) +DECLARE_EVENT_CLASS(snd_soc_preg, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val), + + TP_STRUCT__entry( + __string( name, platform->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, platform->name); + tp_assign(id, platform->id); + tp_assign(reg, reg); + tp_assign(val, val); + ), + + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +) + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +) + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +) +#endif + +DECLARE_EVENT_CLASS(snd_soc_card, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, card->name); + tp_assign(val, val); + ), + + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) +) + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +) + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +) + +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + ), + + TP_fast_assign( + tp_strcpy(name, card->name); + ), + + TP_printk("card=%s", __get_str(name)) +) + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +) + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +) + +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val), + + TP_STRUCT__entry( + __string( name, w->name ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, w->name); + tp_assign(val, val); + ), + + TP_printk("widget=%s val=%d", __get_str(name), + (int)__entry->val) +) + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +) + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +) + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) +TRACE_EVENT(snd_soc_dapm_walk_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, power_checks ) + __field( int, path_checks ) + __field( int, neighbour_checks ) + ), + + TP_fast_assign( + tp_strcpy(name, card->name); + tp_assign(power_checks, card->dapm_stats.power_checks); + tp_assign(path_checks, card->dapm_stats.path_checks); + tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks); + ), + + TP_printk("%s: checks %d power, %d path, %d neighbour", + __get_str(name), (int)__entry->power_checks, + (int)__entry->path_checks, (int)__entry->neighbour_checks) +) +#endif + +TRACE_EVENT(snd_soc_jack_irq, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + ), + + TP_printk("%s", __get_str(name)) +) + +TRACE_EVENT(snd_soc_jack_report, + + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), + + TP_ARGS(jack, mask, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, mask ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, jack->jack->name); + tp_assign(mask, mask); + tp_assign(val, val); + ), + + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, + (int)__entry->mask) +) + +TRACE_EVENT(snd_soc_jack_notify, + + TP_PROTO(struct snd_soc_jack *jack, int val), + + TP_ARGS(jack, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, jack->jack->name); + tp_assign(val, val); + ), + + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) +) + +TRACE_EVENT(snd_soc_cache_sync, + + TP_PROTO(struct snd_soc_codec *codec, const char *type, + const char *status), + + TP_ARGS(codec, type, status), + + TP_STRUCT__entry( + __string( name, codec->name ) + __string( status, status ) + __string( type, type ) + __field( int, id ) + ), + + TP_fast_assign( + tp_strcpy(name, codec->name); + tp_strcpy(status, status); + tp_strcpy(type, type); + tp_assign(id, codec->id); + ), + + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), + (int)__entry->id, __get_str(type), __get_str(status)) +) + +#endif /* _TRACE_ASOC_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h new file mode 100644 index 0000000..e02ecf4 --- /dev/null +++ b/instrumentation/events/lttng-module/ext3.h @@ -0,0 +1,870 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext3 + +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EXT3_H + +#include + +#ifndef _TRACE_EXT3_DEF +#define _TRACE_EXT3_DEF +static struct dentry *dentry; +#endif + + +TRACE_EVENT(ext3_free_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( uid_t, uid ) + __field( gid_t, gid ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(mode, inode->i_mode); + tp_assign(uid, inode->i_uid); + tp_assign(gid, inode->i_gid); + tp_assign(blocks, inode->i_blocks); + ), + + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->uid, __entry->gid, + (unsigned long) __entry->blocks) +) + +TRACE_EVENT(ext3_request_inode, + TP_PROTO(struct inode *dir, int mode), + + TP_ARGS(dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + tp_assign(dev, dir->i_sb->s_dev); + tp_assign(dir, dir->i_ino); + tp_assign(mode, mode); + ), + + TP_printk("dev %d,%d dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->dir, __entry->mode) +) + +TRACE_EVENT(ext3_allocate_inode, + TP_PROTO(struct inode *inode, struct inode *dir, int mode), + + TP_ARGS(inode, dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(dir, dir->i_ino); + tp_assign(mode, mode); + ), + + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->dir, __entry->mode) +) + +TRACE_EVENT(ext3_evict_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, nlink ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(nlink, inode->i_nlink); + ), + + TP_printk("dev %d,%d ino %lu nlink %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->nlink) +) + +TRACE_EVENT(ext3_drop_inode, + TP_PROTO(struct inode *inode, int drop), + + TP_ARGS(inode, drop), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, drop ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(drop, drop); + ), + + TP_printk("dev %d,%d ino %lu drop %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->drop) +) + +TRACE_EVENT(ext3_mark_inode_dirty, + TP_PROTO(struct inode *inode, unsigned long IP), + + TP_ARGS(inode, IP), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field(unsigned long, ip ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(ip, IP); + ), + + TP_printk("dev %d,%d ino %lu caller %pF", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (void *)__entry->ip) +) + +TRACE_EVENT(ext3_write_begin, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), + + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, flags ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(pos, pos); + tp_assign(len, len); + tp_assign(flags, flags); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->flags) +) + +DECLARE_EVENT_CLASS(ext3__write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(pos, pos); + tp_assign(len, len); + tp_assign(copied, copied); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->copied) +) + +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +) + +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +) + +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +) + +DECLARE_EVENT_CLASS(ext3__page_op, + TP_PROTO(struct page *page), + + TP_ARGS(page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + tp_assign(index, page->index); + tp_assign(ino, page->mapping->host->i_ino); + tp_assign(dev, page->mapping->host->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu page_index %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->index) +) + +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_readpage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_releasepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +TRACE_EVENT(ext3_invalidatepage, + TP_PROTO(struct page *page, unsigned long offset), + + TP_ARGS(page, offset), + + TP_STRUCT__entry( + __field( pgoff_t, index ) + __field( unsigned long, offset ) + __field( ino_t, ino ) + __field( dev_t, dev ) + + ), + + TP_fast_assign( + tp_assign(index, page->index); + tp_assign(offset, offset); + tp_assign(ino, page->mapping->host->i_ino); + tp_assign(dev, page->mapping->host->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->index, __entry->offset) +) + +TRACE_EVENT(ext3_discard_blocks, + TP_PROTO(struct super_block *sb, unsigned long blk, + unsigned long count), + + TP_ARGS(sb, blk, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, blk ) + __field( unsigned long, count ) + + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(blk, blk); + tp_assign(count, count); + ), + + TP_printk("dev %d,%d blk %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->blk, __entry->count) +) + +TRACE_EVENT(ext3_request_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count), + + TP_ARGS(inode, goal, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(count, count); + tp_assign(goal, goal); + ), + + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->goal) +) + +TRACE_EVENT(ext3_allocate_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count, unsigned long block), + + TP_ARGS(inode, goal, count, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, block ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(block, block); + tp_assign(count, count); + tp_assign(goal, goal); + ), + + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->block, + __entry->goal) +) + +TRACE_EVENT(ext3_free_blocks, + TP_PROTO(struct inode *inode, unsigned long block, + unsigned long count), + + TP_ARGS(inode, block, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( unsigned long, block ) + __field( unsigned long, count ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(mode, inode->i_mode); + tp_assign(block, block); + tp_assign(count, count); + ), + + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->block, __entry->count) +) + +TRACE_EVENT(ext3_sync_file_enter, + TP_PROTO(struct file *file, int datasync), + + TP_ARGS(file, datasync), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, parent ) + __field( int, datasync ) + ), + + TP_fast_assign( + dentry = file->f_path.dentry; + + tp_assign(dev, dentry->d_inode->i_sb->s_dev); + tp_assign(ino, dentry->d_inode->i_ino); + tp_assign(datasync, datasync); + tp_assign(parent, dentry->d_parent->d_inode->i_ino); + ), + + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->parent, __entry->datasync) +) + +TRACE_EVENT(ext3_sync_file_exit, + TP_PROTO(struct inode *inode, int ret), + + TP_ARGS(inode, ret), + + TP_STRUCT__entry( + __field( int, ret ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(ret, ret); + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +) + +TRACE_EVENT(ext3_sync_fs, + TP_PROTO(struct super_block *sb, int wait), + + TP_ARGS(sb, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(wait, wait); + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +) + +TRACE_EVENT(ext3_rsv_window_add, + TP_PROTO(struct super_block *sb, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(start, rsv_node->rsv_window._rsv_start); + tp_assign(end, rsv_node->rsv_window._rsv_end); + ), + + TP_printk("dev %d,%d start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->start, __entry->end) +) + +TRACE_EVENT(ext3_discard_reservation, + TP_PROTO(struct inode *inode, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(inode, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(start, rsv_node->rsv_window._rsv_start); + tp_assign(end, rsv_node->rsv_window._rsv_end); + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long)__entry->ino, __entry->start, + __entry->end) +) + +TRACE_EVENT(ext3_alloc_new_reservation, + TP_PROTO(struct super_block *sb, unsigned long goal), + + TP_ARGS(sb, goal), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(goal, goal); + ), + + TP_printk("dev %d,%d goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->goal) +) + +TRACE_EVENT(ext3_reserved, + TP_PROTO(struct super_block *sb, unsigned long block, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, block, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, block ) + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(block, block); + tp_assign(start, rsv_node->rsv_window._rsv_start); + tp_assign(end, rsv_node->rsv_window._rsv_end); + tp_assign(dev, sb->s_dev); + ), + + TP_printk("dev %d,%d block %lu, start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->block, __entry->start, __entry->end) +) + +TRACE_EVENT(ext3_forget, + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), + + TP_ARGS(inode, is_metadata, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( int, is_metadata ) + __field( unsigned long, block ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(mode, inode->i_mode); + tp_assign(is_metadata, is_metadata); + tp_assign(block, block); + ), + + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->is_metadata, __entry->block) +) + +TRACE_EVENT(ext3_read_block_bitmap, + TP_PROTO(struct super_block *sb, unsigned int group), + + TP_ARGS(sb, group), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( __u32, group ) + + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(group, group); + ), + + TP_printk("dev %d,%d group %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->group) +) + +TRACE_EVENT(ext3_direct_IO_enter, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), + + TP_ARGS(inode, offset, len, rw), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(pos, offset); + tp_assign(len, len); + tp_assign(rw, rw); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw) +) + +TRACE_EVENT(ext3_direct_IO_exit, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, + int rw, int ret), + + TP_ARGS(inode, offset, len, rw, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(pos, offset); + tp_assign(len, len); + tp_assign(rw, rw); + tp_assign(ret, ret); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw, __entry->ret) +) + +TRACE_EVENT(ext3_unlink_enter, + TP_PROTO(struct inode *parent, struct dentry *dentry), + + TP_ARGS(parent, dentry), + + TP_STRUCT__entry( + __field( ino_t, parent ) + __field( ino_t, ino ) + __field( loff_t, size ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(parent, parent->i_ino); + tp_assign(ino, dentry->d_inode->i_ino); + tp_assign(size, dentry->d_inode->i_size); + tp_assign(dev, dentry->d_inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu size %lld parent %ld", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long)__entry->size, + (unsigned long) __entry->parent) +) + +TRACE_EVENT(ext3_unlink_exit, + TP_PROTO(struct dentry *dentry, int ret), + + TP_ARGS(dentry, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ino, dentry->d_inode->i_ino); + tp_assign(dev, dentry->d_inode->i_sb->s_dev); + tp_assign(ret, ret); + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +) + +DECLARE_EVENT_CLASS(ext3__truncate, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(blocks, inode->i_blocks); + ), + + TP_printk("dev %d,%d ino %lu blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) +) + +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +) + +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +) + +TRACE_EVENT(ext3_get_blocks_enter, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long len, int create), + + TP_ARGS(inode, lblk, len, create), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, len ) + __field( int, create ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(lblk, lblk); + tp_assign(len, len); + tp_assign(create, create); + ), + + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->len, __entry->create) +) + +TRACE_EVENT(ext3_get_blocks_exit, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long pblk, unsigned long len, int ret), + + TP_ARGS(inode, lblk, pblk, len, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, pblk ) + __field( unsigned long, len ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(lblk, lblk); + tp_assign(pblk, pblk); + tp_assign(len, len); + tp_assign(ret, ret); + ), + + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->pblk, + __entry->len, __entry->ret) +) + +TRACE_EVENT(ext3_load_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +) + +#endif /* _TRACE_EXT3_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/gpio.h b/instrumentation/events/lttng-module/gpio.h new file mode 100644 index 0000000..e6002c4 --- /dev/null +++ b/instrumentation/events/lttng-module/gpio.h @@ -0,0 +1,56 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM gpio + +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_GPIO_H + +#include + +TRACE_EVENT(gpio_direction, + + TP_PROTO(unsigned gpio, int in, int err), + + TP_ARGS(gpio, in, err), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, in) + __field(int, err) + ), + + TP_fast_assign( + tp_assign(gpio, gpio); + tp_assign(in, in); + tp_assign(err, err); + ), + + TP_printk("%u %3s (%d)", __entry->gpio, + __entry->in ? "in" : "out", __entry->err) +) + +TRACE_EVENT(gpio_value, + + TP_PROTO(unsigned gpio, int get, int value), + + TP_ARGS(gpio, get, value), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, get) + __field(int, value) + ), + + TP_fast_assign( + tp_assign(gpio, gpio); + tp_assign(get, get); + tp_assign(value, value); + ), + + TP_printk("%u %3s %d", __entry->gpio, + __entry->get ? "get" : "set", __entry->value) +) + +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h new file mode 100644 index 0000000..97ba1e5 --- /dev/null +++ b/instrumentation/events/lttng-module/jbd.h @@ -0,0 +1,243 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd + +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD_H + +#include +#include + +TRACE_EVENT(jbd_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(result, result); + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->result) +) + +DECLARE_EVENT_CLASS(jbd_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +#else + TP_printk("dev %d,%d transaction %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction) +#endif +) + +DEFINE_EVENT(jbd_commit, jbd_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd_commit, jbd_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd_commit, jbd_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +TRACE_EVENT(jbd_drop_transaction, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +#else + TP_printk("dev %d,%d transaction %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction) +#endif +) + +TRACE_EVENT(jbd_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + tp_assign(head, journal->j_tail_sequence); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +#else + TP_printk("dev %d,%d transaction %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->head) +#endif +) + +TRACE_EVENT(jbd_do_submit_data, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +#else + TP_printk("dev %d,%d transaction %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction) +#endif +) + +TRACE_EVENT(jbd_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(tail_sequence, journal->j_tail_sequence); + tp_assign(first_tid, first_tid); + tp_assign(block_nr, block_nr); + tp_assign(freed, freed); + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +) + +TRACE_EVENT(jbd_update_superblock_end, + TP_PROTO(journal_t *journal, int wait), + + TP_ARGS(journal, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(wait, wait); + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +) + +#endif /* _TRACE_JBD_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h new file mode 100644 index 0000000..2e80832 --- /dev/null +++ b/instrumentation/events/lttng-module/jbd2.h @@ -0,0 +1,238 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd2 + +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD2_H + +#include +#include + +#ifndef _TRACE_JBD2_DEF +#define _TRACE_JBD2_DEF +struct transaction_chp_stats_s; +struct transaction_run_stats_s; +#endif + +TRACE_EVENT(jbd2_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(result, result); + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) +) + +DECLARE_EVENT_CLASS(jbd2_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(transaction, commit_transaction->t_tid); + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +) + +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +TRACE_EVENT(jbd2_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(transaction, commit_transaction->t_tid); + tp_assign(head, journal->j_tail_sequence); + ), + + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +) + +TRACE_EVENT(jbd2_submit_inode_data, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +) + +TRACE_EVENT(jbd2_run_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_run_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, wait ) + __field( unsigned long, running ) + __field( unsigned long, locked ) + __field( unsigned long, flushing ) + __field( unsigned long, logging ) + __field( __u32, handle_count ) + __field( __u32, blocks ) + __field( __u32, blocks_logged ) + ), + + TP_fast_assign( + tp_assign(dev, dev); + tp_assign(tid, tid); + tp_assign(wait, stats->rs_wait); + tp_assign(running, stats->rs_running); + tp_assign(locked, stats->rs_locked); + tp_assign(flushing, stats->rs_flushing); + tp_assign(logging, stats->rs_logging); + tp_assign(handle_count, stats->rs_handle_count); + tp_assign(blocks, stats->rs_blocks); + tp_assign(blocks_logged, stats->rs_blocks_logged); + ), + + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " + "logging %u handle_count %u blocks %u blocks_logged %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->wait), + jiffies_to_msecs(__entry->running), + jiffies_to_msecs(__entry->locked), + jiffies_to_msecs(__entry->flushing), + jiffies_to_msecs(__entry->logging), + __entry->handle_count, __entry->blocks, + __entry->blocks_logged) +) + +TRACE_EVENT(jbd2_checkpoint_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_chp_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, chp_time ) + __field( __u32, forced_to_close ) + __field( __u32, written ) + __field( __u32, dropped ) + ), + + TP_fast_assign( + tp_assign(dev, dev); + tp_assign(tid, tid); + tp_assign(chp_time, stats->cs_chp_time); + tp_assign(forced_to_close, stats->cs_forced_to_close); + tp_assign(written, stats->cs_written); + tp_assign(dropped, stats->cs_dropped); + ), + + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " + "written %u dropped %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->chp_time), + __entry->forced_to_close, __entry->written, __entry->dropped) +) + +TRACE_EVENT(jbd2_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(tail_sequence, journal->j_tail_sequence); + tp_assign(first_tid, first_tid); + tp_assign(block_nr, block_nr); + tp_assign(freed, freed); + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +) + +#endif /* _TRACE_JBD2_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h new file mode 100644 index 0000000..04f668b --- /dev/null +++ b/instrumentation/events/lttng-module/kmem.h @@ -0,0 +1,304 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kmem + +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KMEM_H + +DECLARE_EVENT_CLASS(kmem_alloc, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + tp_assign(call_site, call_site); + tp_assign(ptr, ptr); + tp_assign(bytes_req, bytes_req); + tp_assign(bytes_alloc, bytes_alloc); + tp_assign(gfp_flags, gfp_flags); + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags)) +) + +DEFINE_EVENT(kmem_alloc, kmalloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +) + +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +) + +DECLARE_EVENT_CLASS(kmem_alloc_node, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags, + int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + __field( int, node ) + ), + + TP_fast_assign( + tp_assign(call_site, call_site); + tp_assign(ptr, ptr); + tp_assign(bytes_req, bytes_req); + tp_assign(bytes_alloc, bytes_alloc); + tp_assign(gfp_flags, gfp_flags); + tp_assign(node, node); + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags), + __entry->node) +) + +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +) + +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +) + +DECLARE_EVENT_CLASS(kmem_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + ), + + TP_fast_assign( + tp_assign(call_site, call_site); + tp_assign(ptr, ptr); + ), + + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) +) + +DEFINE_EVENT(kmem_free, kfree, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +) + +DEFINE_EVENT(kmem_free, kmem_cache_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +) + +TRACE_EVENT(mm_page_free_direct, + + TP_PROTO(struct page *page, unsigned int order), + + TP_ARGS(page, order), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(order, order); + ), + + TP_printk("page=%p pfn=%lu order=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order) +) + +TRACE_EVENT(mm_pagevec_free, + + TP_PROTO(struct page *page, int cold), + + TP_ARGS(page, cold), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, cold ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(cold, cold); + ), + + TP_printk("page=%p pfn=%lu order=0 cold=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->cold) +) + +TRACE_EVENT(mm_page_alloc, + + TP_PROTO(struct page *page, unsigned int order, + gfp_t gfp_flags, int migratetype), + + TP_ARGS(page, order, gfp_flags, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( gfp_t, gfp_flags ) + __field( int, migratetype ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(order, order); + tp_assign(gfp_flags, gfp_flags); + tp_assign(migratetype, migratetype); + ), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + show_gfp_flags(__entry->gfp_flags)) +) + +DECLARE_EVENT_CLASS(mm_page, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( int, migratetype ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(order, order); + tp_assign(migratetype, migratetype); + ), + + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + __entry->order == 0) +) + +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype) +) + +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", + __entry->page, page_to_pfn(__entry->page), + __entry->order, __entry->migratetype) +) + +TRACE_EVENT(mm_page_alloc_extfrag, + + TP_PROTO(struct page *page, + int alloc_order, int fallback_order, + int alloc_migratetype, int fallback_migratetype), + + TP_ARGS(page, + alloc_order, fallback_order, + alloc_migratetype, fallback_migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, alloc_order ) + __field( int, fallback_order ) + __field( int, alloc_migratetype ) + __field( int, fallback_migratetype ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(alloc_order, alloc_order); + tp_assign(fallback_order, fallback_order); + tp_assign(alloc_migratetype, alloc_migratetype); + tp_assign(fallback_migratetype, fallback_migratetype); + ), + + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->alloc_order, + __entry->fallback_order, + pageblock_order, + __entry->alloc_migratetype, + __entry->fallback_migratetype, + __entry->fallback_order < pageblock_order, + __entry->alloc_migratetype == __entry->fallback_migratetype) +) + +#endif /* _TRACE_KMEM_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/lock.h b/instrumentation/events/lttng-module/lock.h new file mode 100644 index 0000000..75101f6 --- /dev/null +++ b/instrumentation/events/lttng-module/lock.h @@ -0,0 +1,86 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lock + +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_LOCK_H + +#include +#include + +#ifdef CONFIG_LOCKDEP + +TRACE_EVENT(lock_acquire, + + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, + struct lockdep_map *next_lock, unsigned long ip), + + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), + + TP_STRUCT__entry( + __field(unsigned int, flags) + __string(name, lock->name) + __field(void *, lockdep_addr) + ), + + TP_fast_assign( + tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)); + tp_strcpy(name, lock->name); + tp_assign(lockdep_addr, lock); + ), + + TP_printk("%p %s%s%s", __entry->lockdep_addr, + (__entry->flags & 1) ? "try " : "", + (__entry->flags & 2) ? "read " : "", + __get_str(name)) +) + +DECLARE_EVENT_CLASS(lock, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip), + + TP_STRUCT__entry( + __string( name, lock->name ) + __field( void *, lockdep_addr ) + ), + + TP_fast_assign( + tp_strcpy(name, lock->name); + tp_assign(lockdep_addr, lock); + ), + + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) +) + +DEFINE_EVENT(lock, lock_release, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +) + +#ifdef CONFIG_LOCK_STAT + +DEFINE_EVENT(lock, lock_contended, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +) + +DEFINE_EVENT(lock, lock_acquired, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +) + +#endif +#endif + +#endif /* _TRACE_LOCK_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/module.h b/instrumentation/events/lttng-module/module.h new file mode 100644 index 0000000..2e83431 --- /dev/null +++ b/instrumentation/events/lttng-module/module.h @@ -0,0 +1,134 @@ +/* + * Because linux/module.h has tracepoints in the header, and ftrace.h + * eventually includes this file, define_trace.h includes linux/module.h + * But we do not want the module.h to override the TRACE_SYSTEM macro + * variable that define_trace.h is processing, so we only set it + * when module events are being processed, which would happen when + * CREATE_TRACE_POINTS is defined. + */ +#ifdef CREATE_TRACE_POINTS +#undef TRACE_SYSTEM +#define TRACE_SYSTEM module +#endif + +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MODULE_H + +#include + +#ifdef CONFIG_MODULES + +#ifndef _TRACE_MODULE_DEF +#define _TRACE_MODULE_DEF +struct module; + +#define show_module_flags(flags) __print_flags(flags, "", \ + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ + { (1UL << TAINT_FORCED_MODULE), "F" }, \ + { (1UL << TAINT_CRAP), "C" }) +#endif + +TRACE_EVENT(module_load, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __field( unsigned int, taints ) + __string( name, mod->name ) + ), + + TP_fast_assign( + tp_assign(taints, mod->taints); + tp_strcpy(name, mod->name); + ), + + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) +) + +TRACE_EVENT(module_free, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __string( name, mod->name ) + ), + + TP_fast_assign( + tp_strcpy(name, mod->name); + ), + + TP_printk("%s", __get_str(name)) +) + +#ifdef CONFIG_MODULE_UNLOAD +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ + +DECLARE_EVENT_CLASS(module_refcnt, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( int, refcnt ) + __string( name, mod->name ) + ), + + TP_fast_assign( + tp_assign(ip, ip); + tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)); + tp_strcpy(name, mod->name); + ), + + TP_printk("%s call_site=%pf refcnt=%d", + __get_str(name), (void *)__entry->ip, __entry->refcnt) +) + +DEFINE_EVENT(module_refcnt, module_get, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +) + +DEFINE_EVENT(module_refcnt, module_put, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +) +#endif /* CONFIG_MODULE_UNLOAD */ + +TRACE_EVENT(module_request, + + TP_PROTO(char *name, bool wait, unsigned long ip), + + TP_ARGS(name, wait, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( bool, wait ) + __string( name, name ) + ), + + TP_fast_assign( + tp_assign(ip, ip); + tp_assign(wait, wait); + tp_strcpy(name, name); + ), + + TP_printk("%s wait=%d call_site=%pf", + __get_str(name), (int)__entry->wait, (void *)__entry->ip) +) + +#endif /* CONFIG_MODULES */ + +#endif /* _TRACE_MODULE_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/napi.h b/instrumentation/events/lttng-module/napi.h new file mode 100644 index 0000000..58b8336 --- /dev/null +++ b/instrumentation/events/lttng-module/napi.h @@ -0,0 +1,38 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM napi + +#if !defined(_TRACE_NAPI_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NAPI_H_ + +#include +#include +#include + +#define NO_DEV "(no_device)" + +TRACE_EVENT(napi_poll, + + TP_PROTO(struct napi_struct *napi), + + TP_ARGS(napi), + + TP_STRUCT__entry( + __field( struct napi_struct *, napi) + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) + ), + + TP_fast_assign( + tp_assign(napi, napi); + tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV); + ), + + TP_printk("napi poll on napi struct %p for device %s", + __entry->napi, __get_str(dev_name)) +) + +#undef NO_DEV + +#endif /* _TRACE_NAPI_H_ */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h new file mode 100644 index 0000000..c25b0d9 --- /dev/null +++ b/instrumentation/events/lttng-module/net.h @@ -0,0 +1,84 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM net + +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NET_H + +#include +#include +#include +#include + +TRACE_EVENT(net_dev_xmit, + + TP_PROTO(struct sk_buff *skb, + int rc, + struct net_device *dev, + unsigned int skb_len), + + TP_ARGS(skb, rc, dev, skb_len), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __field( int, rc ) + __string( name, dev->name ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, skb_len); + tp_assign(rc, rc); + tp_strcpy(name, dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) +) + +DECLARE_EVENT_CLASS(net_dev_template, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __string( name, skb->dev->name ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, skb->len); + tp_strcpy(name, skb->dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u", + __get_str(name), __entry->skbaddr, __entry->len) +) + +DEFINE_EVENT(net_dev_template, net_dev_queue, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +) + +DEFINE_EVENT(net_dev_template, netif_receive_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +) + +DEFINE_EVENT(net_dev_template, netif_rx, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +) +#endif /* _TRACE_NET_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h new file mode 100644 index 0000000..05aced7 --- /dev/null +++ b/instrumentation/events/lttng-module/power.h @@ -0,0 +1,240 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM power + +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_POWER_H + +#include +#include + +DECLARE_EVENT_CLASS(cpu, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id), + + TP_STRUCT__entry( + __field( u32, state ) + __field( u32, cpu_id ) + ), + + TP_fast_assign( + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, + (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(cpu, cpu_idle, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id) +) + +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING + +#define PWR_EVENT_EXIT -1 +#endif + +DEFINE_EVENT(cpu, cpu_frequency, + + TP_PROTO(unsigned int frequency, unsigned int cpu_id), + + TP_ARGS(frequency, cpu_id) +) + +TRACE_EVENT(machine_suspend, + + TP_PROTO(unsigned int state), + + TP_ARGS(state), + + TP_STRUCT__entry( + __field( u32, state ) + ), + + TP_fast_assign( + tp_assign(state, state); + ), + + TP_printk("state=%lu", (unsigned long)__entry->state) +) + +/* This code will be removed after deprecation time exceeded (2.6.41) */ +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED + +/* + * The power events are used for cpuidle & suspend (power_start, power_end) + * and for cpufreq (power_frequency) + */ +DECLARE_EVENT_CLASS(power, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id), + + TP_STRUCT__entry( + __field( u64, type ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_assign(type, type); + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(power, power_start, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +) + +DEFINE_EVENT(power, power_frequency, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +) + +TRACE_EVENT(power_end, + + TP_PROTO(unsigned int cpu_id), + + TP_ARGS(cpu_id), + + TP_STRUCT__entry( + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) + +) + +/* Deprecated dummy functions must be protected against multi-declartion */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED + +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; + +/* These dummy declaration have to be ripped out when the deprecated + events get removed */ +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; +static inline void trace_power_end(u64 cpuid) {}; +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +/* + * The clock events are used for clock enable/disable and for + * clock rate change + */ +DECLARE_EVENT_CLASS(clock, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(clock, clock_enable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) + +DEFINE_EVENT(clock, clock_disable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) + +DEFINE_EVENT(clock, clock_set_rate, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) + +/* + * The power domain events are used for power domains transitions + */ +DECLARE_EVENT_CLASS(power_domain, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); +), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(power_domain, power_domain_target, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/regulator.h b/instrumentation/events/lttng-module/regulator.h new file mode 100644 index 0000000..e94da7c --- /dev/null +++ b/instrumentation/events/lttng-module/regulator.h @@ -0,0 +1,141 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM regulator + +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_REGULATOR_H + +#include +#include + +/* + * Events which just log themselves and the regulator name for enable/disable + * type tracking. + */ +DECLARE_EVENT_CLASS(regulator_basic, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + ), + + TP_printk("name=%s", __get_str(name)) + +) + +DEFINE_EVENT(regulator_basic, regulator_enable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_enable_delay, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_enable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_disable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_disable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +/* + * Events that take a range of numerical values, mostly for voltages + * and so on. + */ +DECLARE_EVENT_CLASS(regulator_range, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max), + + TP_STRUCT__entry( + __string( name, name ) + __field( int, min ) + __field( int, max ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(min, min); + tp_assign(max, max); + ), + + TP_printk("name=%s (%d-%d)", __get_str(name), + (int)__entry->min, (int)__entry->max) +) + +DEFINE_EVENT(regulator_range, regulator_set_voltage, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max) + +) + + +/* + * Events that take a single value, mostly for readback and refcounts. + */ +DECLARE_EVENT_CLASS(regulator_value, + + TP_PROTO(const char *name, unsigned int val), + + TP_ARGS(name, val), + + TP_STRUCT__entry( + __string( name, name ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(val, val); + ), + + TP_printk("name=%s, val=%u", __get_str(name), + (int)__entry->val) +) + +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, + + TP_PROTO(const char *name, unsigned int value), + + TP_ARGS(name, value) + +) + +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h new file mode 100644 index 0000000..27362f8 --- /dev/null +++ b/instrumentation/events/lttng-module/scsi.h @@ -0,0 +1,369 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM scsi + +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SCSI_H + +#include +#include +#include +#include + +#ifndef _TRACE_SCSI_DEF +#define _TRACE_SCSI_DEF + +#define scsi_opcode_name(opcode) { opcode, #opcode } +#define show_opcode_name(val) \ + __print_symbolic(val, \ + scsi_opcode_name(TEST_UNIT_READY), \ + scsi_opcode_name(REZERO_UNIT), \ + scsi_opcode_name(REQUEST_SENSE), \ + scsi_opcode_name(FORMAT_UNIT), \ + scsi_opcode_name(READ_BLOCK_LIMITS), \ + scsi_opcode_name(REASSIGN_BLOCKS), \ + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ + scsi_opcode_name(READ_6), \ + scsi_opcode_name(WRITE_6), \ + scsi_opcode_name(SEEK_6), \ + scsi_opcode_name(READ_REVERSE), \ + scsi_opcode_name(WRITE_FILEMARKS), \ + scsi_opcode_name(SPACE), \ + scsi_opcode_name(INQUIRY), \ + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ + scsi_opcode_name(MODE_SELECT), \ + scsi_opcode_name(RESERVE), \ + scsi_opcode_name(RELEASE), \ + scsi_opcode_name(COPY), \ + scsi_opcode_name(ERASE), \ + scsi_opcode_name(MODE_SENSE), \ + scsi_opcode_name(START_STOP), \ + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ + scsi_opcode_name(SEND_DIAGNOSTIC), \ + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ + scsi_opcode_name(SET_WINDOW), \ + scsi_opcode_name(READ_CAPACITY), \ + scsi_opcode_name(READ_10), \ + scsi_opcode_name(WRITE_10), \ + scsi_opcode_name(SEEK_10), \ + scsi_opcode_name(POSITION_TO_ELEMENT), \ + scsi_opcode_name(WRITE_VERIFY), \ + scsi_opcode_name(VERIFY), \ + scsi_opcode_name(SEARCH_HIGH), \ + scsi_opcode_name(SEARCH_EQUAL), \ + scsi_opcode_name(SEARCH_LOW), \ + scsi_opcode_name(SET_LIMITS), \ + scsi_opcode_name(PRE_FETCH), \ + scsi_opcode_name(READ_POSITION), \ + scsi_opcode_name(SYNCHRONIZE_CACHE), \ + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ + scsi_opcode_name(READ_DEFECT_DATA), \ + scsi_opcode_name(MEDIUM_SCAN), \ + scsi_opcode_name(COMPARE), \ + scsi_opcode_name(COPY_VERIFY), \ + scsi_opcode_name(WRITE_BUFFER), \ + scsi_opcode_name(READ_BUFFER), \ + scsi_opcode_name(UPDATE_BLOCK), \ + scsi_opcode_name(READ_LONG), \ + scsi_opcode_name(WRITE_LONG), \ + scsi_opcode_name(CHANGE_DEFINITION), \ + scsi_opcode_name(WRITE_SAME), \ + scsi_opcode_name(UNMAP), \ + scsi_opcode_name(READ_TOC), \ + scsi_opcode_name(LOG_SELECT), \ + scsi_opcode_name(LOG_SENSE), \ + scsi_opcode_name(XDWRITEREAD_10), \ + scsi_opcode_name(MODE_SELECT_10), \ + scsi_opcode_name(RESERVE_10), \ + scsi_opcode_name(RELEASE_10), \ + scsi_opcode_name(MODE_SENSE_10), \ + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ + scsi_opcode_name(REPORT_LUNS), \ + scsi_opcode_name(MAINTENANCE_IN), \ + scsi_opcode_name(MAINTENANCE_OUT), \ + scsi_opcode_name(MOVE_MEDIUM), \ + scsi_opcode_name(EXCHANGE_MEDIUM), \ + scsi_opcode_name(READ_12), \ + scsi_opcode_name(WRITE_12), \ + scsi_opcode_name(WRITE_VERIFY_12), \ + scsi_opcode_name(SEARCH_HIGH_12), \ + scsi_opcode_name(SEARCH_EQUAL_12), \ + scsi_opcode_name(SEARCH_LOW_12), \ + scsi_opcode_name(READ_ELEMENT_STATUS), \ + scsi_opcode_name(SEND_VOLUME_TAG), \ + scsi_opcode_name(WRITE_LONG_2), \ + scsi_opcode_name(READ_16), \ + scsi_opcode_name(WRITE_16), \ + scsi_opcode_name(VERIFY_16), \ + scsi_opcode_name(WRITE_SAME_16), \ + scsi_opcode_name(SERVICE_ACTION_IN), \ + scsi_opcode_name(SAI_READ_CAPACITY_16), \ + scsi_opcode_name(SAI_GET_LBA_STATUS), \ + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ + scsi_opcode_name(MO_SET_TARGET_PGS), \ + scsi_opcode_name(READ_32), \ + scsi_opcode_name(WRITE_32), \ + scsi_opcode_name(WRITE_SAME_32), \ + scsi_opcode_name(ATA_16), \ + scsi_opcode_name(ATA_12)) + +#define scsi_hostbyte_name(result) { result, #result } +#define show_hostbyte_name(val) \ + __print_symbolic(val, \ + scsi_hostbyte_name(DID_OK), \ + scsi_hostbyte_name(DID_NO_CONNECT), \ + scsi_hostbyte_name(DID_BUS_BUSY), \ + scsi_hostbyte_name(DID_TIME_OUT), \ + scsi_hostbyte_name(DID_BAD_TARGET), \ + scsi_hostbyte_name(DID_ABORT), \ + scsi_hostbyte_name(DID_PARITY), \ + scsi_hostbyte_name(DID_ERROR), \ + scsi_hostbyte_name(DID_RESET), \ + scsi_hostbyte_name(DID_BAD_INTR), \ + scsi_hostbyte_name(DID_PASSTHROUGH), \ + scsi_hostbyte_name(DID_SOFT_ERROR), \ + scsi_hostbyte_name(DID_IMM_RETRY), \ + scsi_hostbyte_name(DID_REQUEUE), \ + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) + +#define scsi_driverbyte_name(result) { result, #result } +#define show_driverbyte_name(val) \ + __print_symbolic(val, \ + scsi_driverbyte_name(DRIVER_OK), \ + scsi_driverbyte_name(DRIVER_BUSY), \ + scsi_driverbyte_name(DRIVER_SOFT), \ + scsi_driverbyte_name(DRIVER_MEDIA), \ + scsi_driverbyte_name(DRIVER_ERROR), \ + scsi_driverbyte_name(DRIVER_INVALID), \ + scsi_driverbyte_name(DRIVER_TIMEOUT), \ + scsi_driverbyte_name(DRIVER_HARD), \ + scsi_driverbyte_name(DRIVER_SENSE)) + +#define scsi_msgbyte_name(result) { result, #result } +#define show_msgbyte_name(val) \ + __print_symbolic(val, \ + scsi_msgbyte_name(COMMAND_COMPLETE), \ + scsi_msgbyte_name(EXTENDED_MESSAGE), \ + scsi_msgbyte_name(SAVE_POINTERS), \ + scsi_msgbyte_name(RESTORE_POINTERS), \ + scsi_msgbyte_name(DISCONNECT), \ + scsi_msgbyte_name(INITIATOR_ERROR), \ + scsi_msgbyte_name(ABORT_TASK_SET), \ + scsi_msgbyte_name(MESSAGE_REJECT), \ + scsi_msgbyte_name(NOP), \ + scsi_msgbyte_name(MSG_PARITY_ERROR), \ + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ + scsi_msgbyte_name(TARGET_RESET), \ + scsi_msgbyte_name(ABORT_TASK), \ + scsi_msgbyte_name(CLEAR_TASK_SET), \ + scsi_msgbyte_name(INITIATE_RECOVERY), \ + scsi_msgbyte_name(RELEASE_RECOVERY), \ + scsi_msgbyte_name(CLEAR_ACA), \ + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ + scsi_msgbyte_name(ACA), \ + scsi_msgbyte_name(QAS_REQUEST), \ + scsi_msgbyte_name(BUS_DEVICE_RESET), \ + scsi_msgbyte_name(ABORT)) + +#define scsi_statusbyte_name(result) { result, #result } +#define show_statusbyte_name(val) \ + __print_symbolic(val, \ + scsi_statusbyte_name(SAM_STAT_GOOD), \ + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_BUSY), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) + +#define scsi_prot_op_name(result) { result, #result } +#define show_prot_op_name(val) \ + __print_symbolic(val, \ + scsi_prot_op_name(SCSI_PROT_NORMAL), \ + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) + +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) +#endif + +TRACE_EVENT(scsi_dispatch_cmd_start, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + tp_assign(host_no, cmd->device->host->host_no); + tp_assign(channel, cmd->device->channel); + tp_assign(id, cmd->device->id); + tp_assign(lun, cmd->device->lun); + tp_assign(opcode, cmd->cmnd[0]); + tp_assign(cmd_len, cmd->cmd_len); + tp_assign(data_sglen, scsi_sg_count(cmd)); + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); + tp_assign(prot_op, scsi_get_prot_op(cmd)); + tp_memcpy_dyn(cmnd, cmd->cmnd); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) +) + +TRACE_EVENT(scsi_dispatch_cmd_error, + + TP_PROTO(struct scsi_cmnd *cmd, int rtn), + + TP_ARGS(cmd, rtn), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, rtn ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + tp_assign(host_no, cmd->device->host->host_no); + tp_assign(channel, cmd->device->channel); + tp_assign(id, cmd->device->id); + tp_assign(lun, cmd->device->lun); + tp_assign(rtn, rtn); + tp_assign(opcode, cmd->cmnd[0]); + tp_assign(cmd_len, cmd->cmd_len); + tp_assign(data_sglen, scsi_sg_count(cmd)); + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); + tp_assign(prot_op, scsi_get_prot_op(cmd)); + tp_memcpy_dyn(cmnd, cmd->cmnd); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + __entry->rtn) +) + +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, result ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + tp_assign(host_no, cmd->device->host->host_no); + tp_assign(channel, cmd->device->channel); + tp_assign(id, cmd->device->id); + tp_assign(lun, cmd->device->lun); + tp_assign(result, cmd->result); + tp_assign(opcode, cmd->cmnd[0]); + tp_assign(cmd_len, cmd->cmd_len); + tp_assign(data_sglen, scsi_sg_count(cmd)); + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); + tp_assign(prot_op, scsi_get_prot_op(cmd)); + tp_memcpy_dyn(cmnd, cmd->cmnd); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ + "%s host=%s message=%s status=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + show_driverbyte_name(((__entry->result) >> 24) & 0xff), + show_hostbyte_name(((__entry->result) >> 16) & 0xff), + show_msgbyte_name(((__entry->result) >> 8) & 0xff), + show_statusbyte_name(__entry->result & 0xff)) +) + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)) + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)) + +TRACE_EVENT(scsi_eh_wakeup, + + TP_PROTO(struct Scsi_Host *shost), + + TP_ARGS(shost), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + ), + + TP_fast_assign( + tp_assign(host_no, shost->host_no); + ), + + TP_printk("host_no=%u", __entry->host_no) +) + +#endif /* _TRACE_SCSI_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/skb.h b/instrumentation/events/lttng-module/skb.h new file mode 100644 index 0000000..9a79449 --- /dev/null +++ b/instrumentation/events/lttng-module/skb.h @@ -0,0 +1,75 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM skb + +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SKB_H + +#include +#include +#include + +/* + * Tracepoint for free an sk_buff: + */ +TRACE_EVENT(kfree_skb, + + TP_PROTO(struct sk_buff *skb, void *location), + + TP_ARGS(skb, location), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( void *, location ) + __field( unsigned short, protocol ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(location, location); + tp_assign(protocol, ntohs(skb->protocol)); + ), + + TP_printk("skbaddr=%p protocol=%u location=%p", + __entry->skbaddr, __entry->protocol, __entry->location) +) + +TRACE_EVENT(consume_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + ), + + TP_printk("skbaddr=%p", __entry->skbaddr) +) + +TRACE_EVENT(skb_copy_datagram_iovec, + + TP_PROTO(const struct sk_buff *skb, int len), + + TP_ARGS(skb, len), + + TP_STRUCT__entry( + __field( const void *, skbaddr ) + __field( int, len ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, len); + ), + + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) +) + +#endif /* _TRACE_SKB_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h new file mode 100644 index 0000000..246ea58 --- /dev/null +++ b/instrumentation/events/lttng-module/sock.h @@ -0,0 +1,68 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sock + +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SOCK_H + +#include +#include + +TRACE_EVENT(sock_rcvqueue_full, + + TP_PROTO(struct sock *sk, struct sk_buff *skb), + + TP_ARGS(sk, skb), + + TP_STRUCT__entry( + __field(int, rmem_alloc) + __field(unsigned int, truesize) + __field(int, sk_rcvbuf) + ), + + TP_fast_assign( + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); + tp_assign(truesize, skb->truesize); + tp_assign(sk_rcvbuf, sk->sk_rcvbuf); + ), + + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) +) + +TRACE_EVENT(sock_exceed_buf_limit, + + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), + + TP_ARGS(sk, prot, allocated), + + TP_STRUCT__entry( + __string(name, prot->name) + __field(long *, sysctl_mem) + __field(long, allocated) + __field(int, sysctl_rmem) + __field(int, rmem_alloc) + ), + + TP_fast_assign( + tp_strcpy(name, prot->name); + tp_assign(sysctl_mem, prot->sysctl_mem); + tp_assign(allocated, allocated); + tp_assign(sysctl_rmem, prot->sysctl_rmem[0]); + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); + ), + + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " + "sysctl_rmem=%d rmem_alloc=%d", + __entry->name, + __entry->sysctl_mem[0], + __entry->sysctl_mem[1], + __entry->sysctl_mem[2], + __entry->allocated, + __entry->sysctl_rmem, + __entry->rmem_alloc) +) + +#endif /* _TRACE_SOCK_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/udp.h b/instrumentation/events/lttng-module/udp.h new file mode 100644 index 0000000..304ea95 --- /dev/null +++ b/instrumentation/events/lttng-module/udp.h @@ -0,0 +1,32 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM udp + +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_UDP_H + +#include +#include + +TRACE_EVENT(udp_fail_queue_rcv_skb, + + TP_PROTO(int rc, struct sock *sk), + + TP_ARGS(rc, sk), + + TP_STRUCT__entry( + __field(int, rc) + __field(__u16, lport) + ), + + TP_fast_assign( + tp_assign(rc, rc); + tp_assign(lport, inet_sk(sk)->inet_num); + ), + + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) +) + +#endif /* _TRACE_UDP_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h new file mode 100644 index 0000000..aa022e2 --- /dev/null +++ b/instrumentation/events/lttng-module/vmscan.h @@ -0,0 +1,499 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vmscan + +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_VMSCAN_H + +TRACE_EVENT(mm_vmscan_kswapd_sleep, + + TP_PROTO(int nid), + + TP_ARGS(nid), + + TP_STRUCT__entry( + __field( int, nid ) + ), + + TP_fast_assign( + tp_assign(nid, nid); + ), + + TP_printk("nid=%d", __entry->nid) +) + +TRACE_EVENT(mm_vmscan_kswapd_wake, + + TP_PROTO(int nid, int order), + + TP_ARGS(nid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, order ) + ), + + TP_fast_assign( + tp_assign(nid, nid); + tp_assign(order, order); + ), + + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) +) + +TRACE_EVENT(mm_vmscan_wakeup_kswapd, + + TP_PROTO(int nid, int zid, int order), + + TP_ARGS(nid, zid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, zid ) + __field( int, order ) + ), + + TP_fast_assign( + tp_assign(nid, nid); + tp_assign(zid, zid); + tp_assign(order, order); + ), + + TP_printk("nid=%d zid=%d order=%d", + __entry->nid, + __entry->zid, + __entry->order) +) + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags), + + TP_STRUCT__entry( + __field( int, order ) + __field( int, may_writepage ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + tp_assign(order, order); + tp_assign(may_writepage, may_writepage); + tp_assign(gfp_flags, gfp_flags); + ), + + TP_printk("order=%d may_writepage=%d gfp_flags=%s", + __entry->order, + __entry->may_writepage, + show_gfp_flags(__entry->gfp_flags)) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +) + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed), + + TP_STRUCT__entry( + __field( unsigned long, nr_reclaimed ) + ), + + TP_fast_assign( + tp_assign(nr_reclaimed, nr_reclaimed); + ), + + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +) + +TRACE_EVENT(mm_shrink_slab_start, + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, + long nr_objects_to_shrink, unsigned long pgs_scanned, + unsigned long lru_pgs, unsigned long cache_items, + unsigned long long delta, unsigned long total_scan), + + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, + cache_items, delta, total_scan), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, nr_objects_to_shrink) + __field(gfp_t, gfp_flags) + __field(unsigned long, pgs_scanned) + __field(unsigned long, lru_pgs) + __field(unsigned long, cache_items) + __field(unsigned long long, delta) + __field(unsigned long, total_scan) + ), + + TP_fast_assign( + tp_assign(shr,shr); + tp_assign(shrink, shr->shrink); + tp_assign(nr_objects_to_shrink, nr_objects_to_shrink); + tp_assign(gfp_flags, sc->gfp_mask); + tp_assign(pgs_scanned, pgs_scanned); + tp_assign(lru_pgs, lru_pgs); + tp_assign(cache_items, cache_items); + tp_assign(delta, delta); + tp_assign(total_scan, total_scan); + ), + + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", + __entry->shrink, + __entry->shr, + __entry->nr_objects_to_shrink, + show_gfp_flags(__entry->gfp_flags), + __entry->pgs_scanned, + __entry->lru_pgs, + __entry->cache_items, + __entry->delta, + __entry->total_scan) +) + +TRACE_EVENT(mm_shrink_slab_end, + TP_PROTO(struct shrinker *shr, int shrinker_retval, + long unused_scan_cnt, long new_scan_cnt), + + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, unused_scan) + __field(long, new_scan) + __field(int, retval) + __field(long, total_scan) + ), + + TP_fast_assign( + tp_assign(shr, shr); + tp_assign(shrink, shr->shrink); + tp_assign(unused_scan, unused_scan_cnt); + tp_assign(new_scan, new_scan_cnt); + tp_assign(retval, shrinker_retval); + tp_assign(total_scan, new_scan_cnt - unused_scan_cnt); + ), + + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", + __entry->shrink, + __entry->shr, + __entry->unused_scan, + __entry->new_scan, + __entry->total_scan, + __entry->retval) +) + +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + isolate_mode_t isolate_mode), +#else + isolate_mode_t isolate_mode, + int file), +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), +#else + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file), +#endif + + TP_STRUCT__entry( + __field(int, order) + __field(unsigned long, nr_requested) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_taken) + __field(unsigned long, nr_lumpy_taken) + __field(unsigned long, nr_lumpy_dirty) + __field(unsigned long, nr_lumpy_failed) + __field(isolate_mode_t, isolate_mode) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + __field(int, file) +#endif + ), + + TP_fast_assign( + tp_assign(order, order); + tp_assign(nr_requested, nr_requested); + tp_assign(nr_scanned, nr_scanned); + tp_assign(nr_taken, nr_taken); + tp_assign(nr_lumpy_taken, nr_lumpy_taken); + tp_assign(nr_lumpy_dirty, nr_lumpy_dirty); + tp_assign(nr_lumpy_failed, nr_lumpy_failed); + tp_assign(isolate_mode, isolate_mode); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + tp_assign(file, file); +#endif + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", +#else + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", +#endif + __entry->isolate_mode, + __entry->order, + __entry->nr_requested, + __entry->nr_scanned, + __entry->nr_taken, + __entry->nr_lumpy_taken, + __entry->nr_lumpy_dirty, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + __entry->nr_lumpy_failed) +#else + __entry->nr_lumpy_failed, + __entry->file) +#endif +) + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, +#endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + isolate_mode_t isolate_mode), +#else + isolate_mode_t isolate_mode, + int file), +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) +#else + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) +#endif + +) + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, +#endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + isolate_mode_t isolate_mode), +#else + isolate_mode_t isolate_mode, + int file), +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) +#else + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) +#endif + +) + +TRACE_EVENT(mm_vmscan_writepage, + + TP_PROTO(struct page *page, + int reclaim_flags), + + TP_ARGS(page, reclaim_flags), + + TP_STRUCT__entry( + __field(struct page *, page) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(reclaim_flags, reclaim_flags); + ), + + TP_printk("page=%p pfn=%lu flags=%s", + __entry->page, + page_to_pfn(__entry->page), + show_reclaim_flags(__entry->reclaim_flags)) +) + +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, + + TP_PROTO(int nid, int zid, + unsigned long nr_scanned, unsigned long nr_reclaimed, + int priority, int reclaim_flags), + + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), + + TP_STRUCT__entry( + __field(int, nid) + __field(int, zid) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_reclaimed) + __field(int, priority) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + tp_assign(nid, nid); + tp_assign(zid, zid); + tp_assign(nr_scanned, nr_scanned); + tp_assign(nr_reclaimed, nr_reclaimed); + tp_assign(priority, priority); + tp_assign(reclaim_flags, reclaim_flags); + ), + + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", + __entry->nid, __entry->zid, + __entry->nr_scanned, __entry->nr_reclaimed, + __entry->priority, + show_reclaim_flags(__entry->reclaim_flags)) +) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + +TRACE_EVENT(replace_swap_token, + TP_PROTO(struct mm_struct *old_mm, + struct mm_struct *new_mm), + + TP_ARGS(old_mm, new_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, old_mm) + __field(unsigned int, old_prio) + __field(struct mm_struct*, new_mm) + __field(unsigned int, new_prio) + ), + + TP_fast_assign( + tp_assign(old_mm, old_mm); + tp_assign(old_prio, old_mm ? old_mm->token_priority : 0); + tp_assign(new_mm, new_mm); + tp_assign(new_prio, new_mm->token_priority); + ), + + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", + __entry->old_mm, __entry->old_prio, + __entry->new_mm, __entry->new_prio) +) + +DECLARE_EVENT_CLASS(put_swap_token_template, + TP_PROTO(struct mm_struct *swap_token_mm), + + TP_ARGS(swap_token_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, swap_token_mm) + ), + + TP_fast_assign( + tp_assign(swap_token_mm, swap_token_mm); + ), + + TP_printk("token_mm=%p", __entry->swap_token_mm) +) + +DEFINE_EVENT(put_swap_token_template, put_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm) +) + +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm), + TP_CONDITION(swap_token_mm != NULL) +) + +TRACE_EVENT_CONDITION(update_swap_token_priority, + TP_PROTO(struct mm_struct *mm, + unsigned int old_prio, + struct mm_struct *swap_token_mm), + + TP_ARGS(mm, old_prio, swap_token_mm), + + TP_CONDITION(mm->token_priority != old_prio), + + TP_STRUCT__entry( + __field(struct mm_struct*, mm) + __field(unsigned int, old_prio) + __field(unsigned int, new_prio) + __field(struct mm_struct*, swap_token_mm) + __field(unsigned int, swap_token_prio) + ), + + TP_fast_assign( + tp_assign(mm, mm); + tp_assign(old_prio, old_prio); + tp_assign(new_prio, mm->token_priority); + tp_assign(swap_token_mm, swap_token_mm); + tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0); + ), + + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", + __entry->mm, __entry->old_prio, __entry->new_prio, + __entry->swap_token_mm, __entry->swap_token_prio) +) + +#endif + +#endif /* _TRACE_VMSCAN_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/mainline/asoc.h b/instrumentation/events/mainline/asoc.h new file mode 100644 index 0000000..ab26f8a --- /dev/null +++ b/instrumentation/events/mainline/asoc.h @@ -0,0 +1,330 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM asoc + +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ASOC_H + +#include +#include + +struct snd_soc_jack; +struct snd_soc_codec; +struct snd_soc_platform; +struct snd_soc_card; +struct snd_soc_dapm_widget; + +/* + * Log register events + */ +DECLARE_EVENT_CLASS(snd_soc_reg, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val), + + TP_STRUCT__entry( + __string( name, codec->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, codec->name); + __entry->id = codec->id; + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +); + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_preg, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val), + + TP_STRUCT__entry( + __string( name, platform->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, platform->name); + __entry->id = platform->id; + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +); + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_card, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + __entry->val = val; + ), + + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) +); + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +); + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + ), + + TP_printk("card=%s", __get_str(name)) +); + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +); + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +); + +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val), + + TP_STRUCT__entry( + __string( name, w->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, w->name); + __entry->val = val; + ), + + TP_printk("widget=%s val=%d", __get_str(name), + (int)__entry->val) +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +TRACE_EVENT(snd_soc_dapm_walk_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, power_checks ) + __field( int, path_checks ) + __field( int, neighbour_checks ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + __entry->power_checks = card->dapm_stats.power_checks; + __entry->path_checks = card->dapm_stats.path_checks; + __entry->neighbour_checks = card->dapm_stats.neighbour_checks; + ), + + TP_printk("%s: checks %d power, %d path, %d neighbour", + __get_str(name), (int)__entry->power_checks, + (int)__entry->path_checks, (int)__entry->neighbour_checks) +); + +TRACE_EVENT(snd_soc_jack_irq, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + __assign_str(name, name); + ), + + TP_printk("%s", __get_str(name)) +); + +TRACE_EVENT(snd_soc_jack_report, + + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), + + TP_ARGS(jack, mask, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, mask ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, jack->jack->name); + __entry->mask = mask; + __entry->val = val; + ), + + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, + (int)__entry->mask) +); + +TRACE_EVENT(snd_soc_jack_notify, + + TP_PROTO(struct snd_soc_jack *jack, int val), + + TP_ARGS(jack, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, jack->jack->name); + __entry->val = val; + ), + + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) +); + +TRACE_EVENT(snd_soc_cache_sync, + + TP_PROTO(struct snd_soc_codec *codec, const char *type, + const char *status), + + TP_ARGS(codec, type, status), + + TP_STRUCT__entry( + __string( name, codec->name ) + __string( status, status ) + __string( type, type ) + __field( int, id ) + ), + + TP_fast_assign( + __assign_str(name, codec->name); + __assign_str(status, status); + __assign_str(type, type); + __entry->id = codec->id; + ), + + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), + (int)__entry->id, __get_str(type), __get_str(status)) +); + +#endif /* _TRACE_ASOC_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/ext3.h b/instrumentation/events/mainline/ext3.h new file mode 100644 index 0000000..7b53c05 --- /dev/null +++ b/instrumentation/events/mainline/ext3.h @@ -0,0 +1,864 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext3 + +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EXT3_H + +#include + +TRACE_EVENT(ext3_free_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( uid_t, uid ) + __field( gid_t, gid ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->uid = inode->i_uid; + __entry->gid = inode->i_gid; + __entry->blocks = inode->i_blocks; + ), + + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->uid, __entry->gid, + (unsigned long) __entry->blocks) +); + +TRACE_EVENT(ext3_request_inode, + TP_PROTO(struct inode *dir, int mode), + + TP_ARGS(dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + __entry->dev = dir->i_sb->s_dev; + __entry->dir = dir->i_ino; + __entry->mode = mode; + ), + + TP_printk("dev %d,%d dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->dir, __entry->mode) +); + +TRACE_EVENT(ext3_allocate_inode, + TP_PROTO(struct inode *inode, struct inode *dir, int mode), + + TP_ARGS(inode, dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->dir = dir->i_ino; + __entry->mode = mode; + ), + + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->dir, __entry->mode) +); + +TRACE_EVENT(ext3_evict_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, nlink ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->nlink = inode->i_nlink; + ), + + TP_printk("dev %d,%d ino %lu nlink %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->nlink) +); + +TRACE_EVENT(ext3_drop_inode, + TP_PROTO(struct inode *inode, int drop), + + TP_ARGS(inode, drop), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, drop ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->drop = drop; + ), + + TP_printk("dev %d,%d ino %lu drop %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->drop) +); + +TRACE_EVENT(ext3_mark_inode_dirty, + TP_PROTO(struct inode *inode, unsigned long IP), + + TP_ARGS(inode, IP), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field(unsigned long, ip ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->ip = IP; + ), + + TP_printk("dev %d,%d ino %lu caller %pF", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (void *)__entry->ip) +); + +TRACE_EVENT(ext3_write_begin, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), + + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, flags ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->flags = flags; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->flags) +); + +DECLARE_EVENT_CLASS(ext3__write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->copied) +); + +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +); + +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +); + +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +); + +DECLARE_EVENT_CLASS(ext3__page_op, + TP_PROTO(struct page *page), + + TP_ARGS(page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + __entry->index = page->index; + __entry->ino = page->mapping->host->i_ino; + __entry->dev = page->mapping->host->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu page_index %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->index) +); + +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_readpage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_releasepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +TRACE_EVENT(ext3_invalidatepage, + TP_PROTO(struct page *page, unsigned long offset), + + TP_ARGS(page, offset), + + TP_STRUCT__entry( + __field( pgoff_t, index ) + __field( unsigned long, offset ) + __field( ino_t, ino ) + __field( dev_t, dev ) + + ), + + TP_fast_assign( + __entry->index = page->index; + __entry->offset = offset; + __entry->ino = page->mapping->host->i_ino; + __entry->dev = page->mapping->host->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->index, __entry->offset) +); + +TRACE_EVENT(ext3_discard_blocks, + TP_PROTO(struct super_block *sb, unsigned long blk, + unsigned long count), + + TP_ARGS(sb, blk, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, blk ) + __field( unsigned long, count ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->blk = blk; + __entry->count = count; + ), + + TP_printk("dev %d,%d blk %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->blk, __entry->count) +); + +TRACE_EVENT(ext3_request_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count), + + TP_ARGS(inode, goal, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->count = count; + __entry->goal = goal; + ), + + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->goal) +); + +TRACE_EVENT(ext3_allocate_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count, unsigned long block), + + TP_ARGS(inode, goal, count, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, block ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->block = block; + __entry->count = count; + __entry->goal = goal; + ), + + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->block, + __entry->goal) +); + +TRACE_EVENT(ext3_free_blocks, + TP_PROTO(struct inode *inode, unsigned long block, + unsigned long count), + + TP_ARGS(inode, block, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( unsigned long, block ) + __field( unsigned long, count ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->block = block; + __entry->count = count; + ), + + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->block, __entry->count) +); + +TRACE_EVENT(ext3_sync_file_enter, + TP_PROTO(struct file *file, int datasync), + + TP_ARGS(file, datasync), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, parent ) + __field( int, datasync ) + ), + + TP_fast_assign( + struct dentry *dentry = file->f_path.dentry; + + __entry->dev = dentry->d_inode->i_sb->s_dev; + __entry->ino = dentry->d_inode->i_ino; + __entry->datasync = datasync; + __entry->parent = dentry->d_parent->d_inode->i_ino; + ), + + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->parent, __entry->datasync) +); + +TRACE_EVENT(ext3_sync_file_exit, + TP_PROTO(struct inode *inode, int ret), + + TP_ARGS(inode, ret), + + TP_STRUCT__entry( + __field( int, ret ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->ret = ret; + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +); + +TRACE_EVENT(ext3_sync_fs, + TP_PROTO(struct super_block *sb, int wait), + + TP_ARGS(sb, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->wait = wait; + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +); + +TRACE_EVENT(ext3_rsv_window_add, + TP_PROTO(struct super_block *sb, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->start = rsv_node->rsv_window._rsv_start; + __entry->end = rsv_node->rsv_window._rsv_end; + ), + + TP_printk("dev %d,%d start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->start, __entry->end) +); + +TRACE_EVENT(ext3_discard_reservation, + TP_PROTO(struct inode *inode, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(inode, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->start = rsv_node->rsv_window._rsv_start; + __entry->end = rsv_node->rsv_window._rsv_end; + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long)__entry->ino, __entry->start, + __entry->end) +); + +TRACE_EVENT(ext3_alloc_new_reservation, + TP_PROTO(struct super_block *sb, unsigned long goal), + + TP_ARGS(sb, goal), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->goal = goal; + ), + + TP_printk("dev %d,%d goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->goal) +); + +TRACE_EVENT(ext3_reserved, + TP_PROTO(struct super_block *sb, unsigned long block, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, block, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, block ) + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->block = block; + __entry->start = rsv_node->rsv_window._rsv_start; + __entry->end = rsv_node->rsv_window._rsv_end; + __entry->dev = sb->s_dev; + ), + + TP_printk("dev %d,%d block %lu, start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->block, __entry->start, __entry->end) +); + +TRACE_EVENT(ext3_forget, + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), + + TP_ARGS(inode, is_metadata, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( int, is_metadata ) + __field( unsigned long, block ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->is_metadata = is_metadata; + __entry->block = block; + ), + + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->is_metadata, __entry->block) +); + +TRACE_EVENT(ext3_read_block_bitmap, + TP_PROTO(struct super_block *sb, unsigned int group), + + TP_ARGS(sb, group), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( __u32, group ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->group = group; + ), + + TP_printk("dev %d,%d group %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->group) +); + +TRACE_EVENT(ext3_direct_IO_enter, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), + + TP_ARGS(inode, offset, len, rw), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->pos = offset; + __entry->len = len; + __entry->rw = rw; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw) +); + +TRACE_EVENT(ext3_direct_IO_exit, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, + int rw, int ret), + + TP_ARGS(inode, offset, len, rw, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->pos = offset; + __entry->len = len; + __entry->rw = rw; + __entry->ret = ret; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw, __entry->ret) +); + +TRACE_EVENT(ext3_unlink_enter, + TP_PROTO(struct inode *parent, struct dentry *dentry), + + TP_ARGS(parent, dentry), + + TP_STRUCT__entry( + __field( ino_t, parent ) + __field( ino_t, ino ) + __field( loff_t, size ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->parent = parent->i_ino; + __entry->ino = dentry->d_inode->i_ino; + __entry->size = dentry->d_inode->i_size; + __entry->dev = dentry->d_inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu size %lld parent %ld", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long)__entry->size, + (unsigned long) __entry->parent) +); + +TRACE_EVENT(ext3_unlink_exit, + TP_PROTO(struct dentry *dentry, int ret), + + TP_ARGS(dentry, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ino = dentry->d_inode->i_ino; + __entry->dev = dentry->d_inode->i_sb->s_dev; + __entry->ret = ret; + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +); + +DECLARE_EVENT_CLASS(ext3__truncate, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->blocks = inode->i_blocks; + ), + + TP_printk("dev %d,%d ino %lu blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) +); + +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +); + +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +); + +TRACE_EVENT(ext3_get_blocks_enter, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long len, int create), + + TP_ARGS(inode, lblk, len, create), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, len ) + __field( int, create ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->lblk = lblk; + __entry->len = len; + __entry->create = create; + ), + + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->len, __entry->create) +); + +TRACE_EVENT(ext3_get_blocks_exit, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long pblk, unsigned long len, int ret), + + TP_ARGS(inode, lblk, pblk, len, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, pblk ) + __field( unsigned long, len ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->lblk = lblk; + __entry->pblk = pblk; + __entry->len = len; + __entry->ret = ret; + ), + + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->pblk, + __entry->len, __entry->ret) +); + +TRACE_EVENT(ext3_load_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +); + +#endif /* _TRACE_EXT3_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/fs_ext3.h b/instrumentation/events/mainline/fs_ext3.h new file mode 100644 index 0000000..76353e4 --- /dev/null +++ b/instrumentation/events/mainline/fs_ext3.h @@ -0,0 +1,1323 @@ +/* + * Written by Stephen C. Tweedie , 1999 + * + * Copyright 1998--1999 Red Hat corp --- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card at masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) + * + * from + * + * linux/include/linux/minix_fs.h + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include +#include +#include +#include +#include + +/* + * The second extended filesystem constants/structures + */ + +/* + * Define EXT3FS_DEBUG to produce debug messages + */ +#undef EXT3FS_DEBUG + +/* + * Define EXT3_RESERVATION to reserve data blocks for expanding files + */ +#define EXT3_DEFAULT_RESERVE_BLOCKS 8 +/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ +#define EXT3_MAX_RESERVE_BLOCKS 1027 +#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 + +/* + * Debug code + */ +#ifdef EXT3FS_DEBUG +#define ext3_debug(f, a...) \ + do { \ + printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ + __FILE__, __LINE__, __func__); \ + printk (KERN_DEBUG f, ## a); \ + } while (0) +#else +#define ext3_debug(f, a...) do {} while (0) +#endif + +/* + * Special inodes numbers + */ +#define EXT3_BAD_INO 1 /* Bad blocks inode */ +#define EXT3_ROOT_INO 2 /* Root inode */ +#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ +#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ +#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ +#define EXT3_JOURNAL_INO 8 /* Journal inode */ + +/* First non-reserved inode for old ext3 filesystems */ +#define EXT3_GOOD_OLD_FIRST_INO 11 + +/* + * Maximal count of links to a file + */ +#define EXT3_LINK_MAX 32000 + +/* + * Macro-instructions used to manage several block sizes + */ +#define EXT3_MIN_BLOCK_SIZE 1024 +#define EXT3_MAX_BLOCK_SIZE 65536 +#define EXT3_MIN_BLOCK_LOG_SIZE 10 +#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) +#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) +#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) +#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) +#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) +#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) + +/* + * Macro-instructions used to manage fragments + */ +#define EXT3_MIN_FRAG_SIZE 1024 +#define EXT3_MAX_FRAG_SIZE 4096 +#define EXT3_MIN_FRAG_LOG_SIZE 10 +#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) +#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) + +/* + * Structure of a blocks group descriptor + */ +struct ext3_group_desc +{ + __le32 bg_block_bitmap; /* Blocks bitmap block */ + __le32 bg_inode_bitmap; /* Inodes bitmap block */ + __le32 bg_inode_table; /* Inodes table block */ + __le16 bg_free_blocks_count; /* Free blocks count */ + __le16 bg_free_inodes_count; /* Free inodes count */ + __le16 bg_used_dirs_count; /* Directories count */ + __u16 bg_pad; + __le32 bg_reserved[3]; +}; + +/* + * Macro-instructions used to manage group descriptors + */ +#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) +#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) +#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) +#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) + +/* + * Constants relative to the data blocks + */ +#define EXT3_NDIR_BLOCKS 12 +#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS +#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1) +#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1) +#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1) + +/* + * Inode flags + */ +#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */ +#define EXT3_UNRM_FL 0x00000002 /* Undelete */ +#define EXT3_COMPR_FL 0x00000004 /* Compress file */ +#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */ +#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */ +#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */ +#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */ +#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */ +/* Reserved for compression usage... */ +#define EXT3_DIRTY_FL 0x00000100 +#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ +#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */ +#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */ +/* End compression flags --- maybe not all used */ +#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */ +#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ +#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ +#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ +#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ +#define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ +#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ + +#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ + +/* Flags that should be inherited by new inodes from their parent. */ +#define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ + EXT3_SYNC_FL | EXT3_NODUMP_FL |\ + EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\ + EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\ + EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL) + +/* Flags that are appropriate for regular files (all but dir-specific ones). */ +#define EXT3_REG_FLMASK (~(EXT3_DIRSYNC_FL | EXT3_TOPDIR_FL)) + +/* Flags that are appropriate for non-directories/regular files. */ +#define EXT3_OTHER_FLMASK (EXT3_NODUMP_FL | EXT3_NOATIME_FL) + +/* Mask out flags that are inappropriate for the given type of inode. */ +static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) +{ + if (S_ISDIR(mode)) + return flags; + else if (S_ISREG(mode)) + return flags & EXT3_REG_FLMASK; + else + return flags & EXT3_OTHER_FLMASK; +} + +/* Used to pass group descriptor data when online resize is done */ +struct ext3_new_group_input { + __u32 group; /* Group number for this data */ + __u32 block_bitmap; /* Absolute block number of block bitmap */ + __u32 inode_bitmap; /* Absolute block number of inode bitmap */ + __u32 inode_table; /* Absolute block number of inode table start */ + __u32 blocks_count; /* Total number of blocks in this group */ + __u16 reserved_blocks; /* Number of reserved blocks in this group */ + __u16 unused; +}; + +/* The struct ext3_new_group_input in kernel space, with free_blocks_count */ +struct ext3_new_group_data { + __u32 group; + __u32 block_bitmap; + __u32 inode_bitmap; + __u32 inode_table; + __u32 blocks_count; + __u16 reserved_blocks; + __u16 unused; + __u32 free_blocks_count; +}; + + +/* + * ioctl commands + */ +#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS +#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS +#define EXT3_IOC_GETVERSION _IOR('f', 3, long) +#define EXT3_IOC_SETVERSION _IOW('f', 4, long) +#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) +#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input) +#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION +#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION +#ifdef CONFIG_JBD_DEBUG +#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) +#endif +#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) +#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long) + +/* + * ioctl commands in 32 bit emulation + */ +#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS +#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS +#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) +#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) +#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) +#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) +#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) +#ifdef CONFIG_JBD_DEBUG +#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) +#endif +#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION +#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION + + +/* + * Mount options + */ +struct ext3_mount_options { + unsigned long s_mount_opt; + uid_t s_resuid; + gid_t s_resgid; + unsigned long s_commit_interval; +#ifdef CONFIG_QUOTA + int s_jquota_fmt; + char *s_qf_names[MAXQUOTAS]; +#endif +}; + +/* + * Structure of an inode on the disk + */ +struct ext3_inode { + __le16 i_mode; /* File mode */ + __le16 i_uid; /* Low 16 bits of Owner Uid */ + __le32 i_size; /* Size in bytes */ + __le32 i_atime; /* Access time */ + __le32 i_ctime; /* Creation time */ + __le32 i_mtime; /* Modification time */ + __le32 i_dtime; /* Deletion Time */ + __le16 i_gid; /* Low 16 bits of Group Id */ + __le16 i_links_count; /* Links count */ + __le32 i_blocks; /* Blocks count */ + __le32 i_flags; /* File flags */ + union { + struct { + __u32 l_i_reserved1; + } linux1; + struct { + __u32 h_i_translator; + } hurd1; + struct { + __u32 m_i_reserved1; + } masix1; + } osd1; /* OS dependent 1 */ + __le32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */ + __le32 i_generation; /* File version (for NFS) */ + __le32 i_file_acl; /* File ACL */ + __le32 i_dir_acl; /* Directory ACL */ + __le32 i_faddr; /* Fragment address */ + union { + struct { + __u8 l_i_frag; /* Fragment number */ + __u8 l_i_fsize; /* Fragment size */ + __u16 i_pad1; + __le16 l_i_uid_high; /* these 2 fields */ + __le16 l_i_gid_high; /* were reserved2[0] */ + __u32 l_i_reserved2; + } linux2; + struct { + __u8 h_i_frag; /* Fragment number */ + __u8 h_i_fsize; /* Fragment size */ + __u16 h_i_mode_high; + __u16 h_i_uid_high; + __u16 h_i_gid_high; + __u32 h_i_author; + } hurd2; + struct { + __u8 m_i_frag; /* Fragment number */ + __u8 m_i_fsize; /* Fragment size */ + __u16 m_pad1; + __u32 m_i_reserved2[2]; + } masix2; + } osd2; /* OS dependent 2 */ + __le16 i_extra_isize; + __le16 i_pad1; +}; + +#define i_size_high i_dir_acl + +#define i_reserved1 osd1.linux1.l_i_reserved1 +#define i_frag osd2.linux2.l_i_frag +#define i_fsize osd2.linux2.l_i_fsize +#define i_uid_low i_uid +#define i_gid_low i_gid +#define i_uid_high osd2.linux2.l_i_uid_high +#define i_gid_high osd2.linux2.l_i_gid_high +#define i_reserved2 osd2.linux2.l_i_reserved2 + +/* + * File system states + */ +#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */ +#define EXT3_ERROR_FS 0x0002 /* Errors detected */ +#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */ + +/* + * Misc. filesystem flags + */ +#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ +#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ +#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ + +/* + * Mount flags + */ +#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */ +/* EXT3_MOUNT_OLDALLOC was there */ +#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */ +#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */ +#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ +#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ +#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ +#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ +#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ +#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */ +#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ +#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ +#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ +#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ +#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ +#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ +#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ +#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ +#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ +#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ +#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ +#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ +#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write + * error in ordered mode */ + +/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ +#ifndef _LINUX_EXT2_FS_H +#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt +#define set_opt(o, opt) o |= EXT3_MOUNT_##opt +#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ + EXT3_MOUNT_##opt) +#else +#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD +#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT +#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS +#endif + +#define ext3_set_bit __set_bit_le +#define ext3_set_bit_atomic ext2_set_bit_atomic +#define ext3_clear_bit __clear_bit_le +#define ext3_clear_bit_atomic ext2_clear_bit_atomic +#define ext3_test_bit test_bit_le +#define ext3_find_next_zero_bit find_next_zero_bit_le + +/* + * Maximal mount counts between two filesystem checks + */ +#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ +#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */ + +/* + * Behaviour when detecting errors + */ +#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */ +#define EXT3_ERRORS_RO 2 /* Remount fs read-only */ +#define EXT3_ERRORS_PANIC 3 /* Panic */ +#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE + +/* + * Structure of the super block + */ +struct ext3_super_block { +/*00*/ __le32 s_inodes_count; /* Inodes count */ + __le32 s_blocks_count; /* Blocks count */ + __le32 s_r_blocks_count; /* Reserved blocks count */ + __le32 s_free_blocks_count; /* Free blocks count */ +/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ + __le32 s_first_data_block; /* First Data Block */ + __le32 s_log_block_size; /* Block size */ + __le32 s_log_frag_size; /* Fragment size */ +/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ + __le32 s_frags_per_group; /* # Fragments per group */ + __le32 s_inodes_per_group; /* # Inodes per group */ + __le32 s_mtime; /* Mount time */ +/*30*/ __le32 s_wtime; /* Write time */ + __le16 s_mnt_count; /* Mount count */ + __le16 s_max_mnt_count; /* Maximal mount count */ + __le16 s_magic; /* Magic signature */ + __le16 s_state; /* File system state */ + __le16 s_errors; /* Behaviour when detecting errors */ + __le16 s_minor_rev_level; /* minor revision level */ +/*40*/ __le32 s_lastcheck; /* time of last check */ + __le32 s_checkinterval; /* max. time between checks */ + __le32 s_creator_os; /* OS */ + __le32 s_rev_level; /* Revision level */ +/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ + __le16 s_def_resgid; /* Default gid for reserved blocks */ + /* + * These fields are for EXT3_DYNAMIC_REV superblocks only. + * + * Note: the difference between the compatible feature set and + * the incompatible feature set is that if there is a bit set + * in the incompatible feature set that the kernel doesn't + * know about, it should refuse to mount the filesystem. + * + * e2fsck's requirements are more strict; if it doesn't know + * about a feature in either the compatible or incompatible + * feature set, it must abort and not try to meddle with + * things it doesn't understand... + */ + __le32 s_first_ino; /* First non-reserved inode */ + __le16 s_inode_size; /* size of inode structure */ + __le16 s_block_group_nr; /* block group # of this superblock */ + __le32 s_feature_compat; /* compatible feature set */ +/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ + __le32 s_feature_ro_compat; /* readonly-compatible feature set */ +/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ +/*78*/ char s_volume_name[16]; /* volume name */ +/*88*/ char s_last_mounted[64]; /* directory where last mounted */ +/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ + /* + * Performance hints. Directory preallocation should only + * happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on. + */ + __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ + __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ + __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ + /* + * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. + */ +/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ +/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ + __le32 s_journal_dev; /* device number of journal file */ + __le32 s_last_orphan; /* start of list of inodes to delete */ + __le32 s_hash_seed[4]; /* HTREE hash seed */ + __u8 s_def_hash_version; /* Default hash version to use */ + __u8 s_reserved_char_pad; + __u16 s_reserved_word_pad; + __le32 s_default_mount_opts; + __le32 s_first_meta_bg; /* First metablock block group */ + __le32 s_mkfs_time; /* When the filesystem was created */ + __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ + /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ +/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ + __le32 s_r_blocks_count_hi; /* Reserved blocks count */ + __le32 s_free_blocks_count_hi; /* Free blocks count */ + __le16 s_min_extra_isize; /* All inodes have at least # bytes */ + __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ + __le32 s_flags; /* Miscellaneous flags */ + __le16 s_raid_stride; /* RAID stride */ + __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ + __le64 s_mmp_block; /* Block for multi-mount protection */ + __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ + __u8 s_log_groups_per_flex; /* FLEX_BG group size */ + __u8 s_reserved_char_pad2; + __le16 s_reserved_pad; + __u32 s_reserved[162]; /* Padding to the end of the block */ +}; + +/* data type for block offset of block group */ +typedef int ext3_grpblk_t; + +/* data type for filesystem-wide blocks number */ +typedef unsigned long ext3_fsblk_t; + +#define E3FSBLK "%lu" + +struct ext3_reserve_window { + ext3_fsblk_t _rsv_start; /* First byte reserved */ + ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ +}; + +struct ext3_reserve_window_node { + struct rb_node rsv_node; + __u32 rsv_goal_size; + __u32 rsv_alloc_hit; + struct ext3_reserve_window rsv_window; +}; + +struct ext3_block_alloc_info { + /* information about reservation window */ + struct ext3_reserve_window_node rsv_window_node; + /* + * was i_next_alloc_block in ext3_inode_info + * is the logical (file-relative) number of the + * most-recently-allocated block in this file. + * We use this for detecting linearly ascending allocation requests. + */ + __u32 last_alloc_logical_block; + /* + * Was i_next_alloc_goal in ext3_inode_info + * is the *physical* companion to i_next_alloc_block. + * it the physical block number of the block which was most-recentl + * allocated to this file. This give us the goal (target) for the next + * allocation when we detect linearly ascending requests. + */ + ext3_fsblk_t last_alloc_physical_block; +}; + +#define rsv_start rsv_window._rsv_start +#define rsv_end rsv_window._rsv_end + +/* + * third extended file system inode data in memory + */ +struct ext3_inode_info { + __le32 i_data[15]; /* unconverted */ + __u32 i_flags; +#ifdef EXT3_FRAGMENTS + __u32 i_faddr; + __u8 i_frag_no; + __u8 i_frag_size; +#endif + ext3_fsblk_t i_file_acl; + __u32 i_dir_acl; + __u32 i_dtime; + + /* + * i_block_group is the number of the block group which contains + * this file's inode. Constant across the lifetime of the inode, + * it is ued for making block allocation decisions - we try to + * place a file's data blocks near its inode block, and new inodes + * near to their parent directory's inode. + */ + __u32 i_block_group; + unsigned long i_state_flags; /* Dynamic state flags for ext3 */ + + /* block reservation info */ + struct ext3_block_alloc_info *i_block_alloc_info; + + __u32 i_dir_start_lookup; +#ifdef CONFIG_EXT3_FS_XATTR + /* + * Extended attributes can be read independently of the main file + * data. Taking i_mutex even when reading would cause contention + * between readers of EAs and writers of regular file data, so + * instead we synchronize on xattr_sem when reading or changing + * EAs. + */ + struct rw_semaphore xattr_sem; +#endif + + struct list_head i_orphan; /* unlinked but open inodes */ + + /* + * i_disksize keeps track of what the inode size is ON DISK, not + * in memory. During truncate, i_size is set to the new size by + * the VFS prior to calling ext3_truncate(), but the filesystem won't + * set i_disksize to 0 until the truncate is actually under way. + * + * The intent is that i_disksize always represents the blocks which + * are used by this file. This allows recovery to restart truncate + * on orphans if we crash during truncate. We actually write i_disksize + * into the on-disk inode when writing inodes out, instead of i_size. + * + * The only time when i_disksize and i_size may be different is when + * a truncate is in progress. The only things which change i_disksize + * are ext3_get_block (growth) and ext3_truncate (shrinkth). + */ + loff_t i_disksize; + + /* on-disk additional length */ + __u16 i_extra_isize; + + /* + * truncate_mutex is for serialising ext3_truncate() against + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's + * data tree are chopped off during truncate. We can't do that in + * ext3 because whenever we perform intermediate commits during + * truncate, the inode and all the metadata blocks *must* be in a + * consistent state which allows truncation of the orphans to restart + * during recovery. Hence we must fix the get_block-vs-truncate race + * by other means, so we have truncate_mutex. + */ + struct mutex truncate_mutex; + + /* + * Transactions that contain inode's metadata needed to complete + * fsync and fdatasync, respectively. + */ + atomic_t i_sync_tid; + atomic_t i_datasync_tid; + + struct inode vfs_inode; +}; + +/* + * third extended-fs super-block data in memory + */ +struct ext3_sb_info { + unsigned long s_frag_size; /* Size of a fragment in bytes */ + unsigned long s_frags_per_block;/* Number of fragments per block */ + unsigned long s_inodes_per_block;/* Number of inodes per block */ + unsigned long s_frags_per_group;/* Number of fragments in a group */ + unsigned long s_blocks_per_group;/* Number of blocks in a group */ + unsigned long s_inodes_per_group;/* Number of inodes in a group */ + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ + unsigned long s_gdb_count; /* Number of group descriptor blocks */ + unsigned long s_desc_per_block; /* Number of group descriptors per block */ + unsigned long s_groups_count; /* Number of groups in the fs */ + unsigned long s_overhead_last; /* Last calculated overhead */ + unsigned long s_blocks_last; /* Last seen block count */ + struct buffer_head * s_sbh; /* Buffer containing the super block */ + struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ + struct buffer_head ** s_group_desc; + unsigned long s_mount_opt; + ext3_fsblk_t s_sb_block; + uid_t s_resuid; + gid_t s_resgid; + unsigned short s_mount_state; + unsigned short s_pad; + int s_addr_per_block_bits; + int s_desc_per_block_bits; + int s_inode_size; + int s_first_ino; + spinlock_t s_next_gen_lock; + u32 s_next_generation; + u32 s_hash_seed[4]; + int s_def_hash_version; + int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ + struct percpu_counter s_freeblocks_counter; + struct percpu_counter s_freeinodes_counter; + struct percpu_counter s_dirs_counter; + struct blockgroup_lock *s_blockgroup_lock; + + /* root of the per fs reservation window tree */ + spinlock_t s_rsv_window_lock; + struct rb_root s_rsv_window_root; + struct ext3_reserve_window_node s_rsv_window_head; + + /* Journaling */ + struct inode * s_journal_inode; + struct journal_s * s_journal; + struct list_head s_orphan; + struct mutex s_orphan_lock; + struct mutex s_resize_lock; + unsigned long s_commit_interval; + struct block_device *journal_bdev; +#ifdef CONFIG_QUOTA + char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ + int s_jquota_fmt; /* Format of quota to use */ +#endif +}; + +static inline spinlock_t * +sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) +{ + return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); +} + +static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} +static inline struct ext3_inode_info *EXT3_I(struct inode *inode) +{ + return container_of(inode, struct ext3_inode_info, vfs_inode); +} + +static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) +{ + return ino == EXT3_ROOT_INO || + ino == EXT3_JOURNAL_INO || + ino == EXT3_RESIZE_INO || + (ino >= EXT3_FIRST_INO(sb) && + ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); +} + +/* + * Inode dynamic state flags + */ +enum { + EXT3_STATE_JDATA, /* journaled data exists */ + EXT3_STATE_NEW, /* inode is newly created */ + EXT3_STATE_XATTR, /* has in-inode xattrs */ + EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ +}; + +static inline int ext3_test_inode_state(struct inode *inode, int bit) +{ + return test_bit(bit, &EXT3_I(inode)->i_state_flags); +} + +static inline void ext3_set_inode_state(struct inode *inode, int bit) +{ + set_bit(bit, &EXT3_I(inode)->i_state_flags); +} + +static inline void ext3_clear_inode_state(struct inode *inode, int bit) +{ + clear_bit(bit, &EXT3_I(inode)->i_state_flags); +} + +#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime + +/* + * Codes for operating systems + */ +#define EXT3_OS_LINUX 0 +#define EXT3_OS_HURD 1 +#define EXT3_OS_MASIX 2 +#define EXT3_OS_FREEBSD 3 +#define EXT3_OS_LITES 4 + +/* + * Revision levels + */ +#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */ +#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ + +#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV +#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV + +#define EXT3_GOOD_OLD_INODE_SIZE 128 + +/* + * Feature set definitions + */ + +#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \ + ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) +#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \ + ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) +#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \ + ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) +#define EXT3_SET_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) +#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) +#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) +#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) +#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) +#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) + +#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001 +#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008 +#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010 +#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020 + +#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 + +#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001 +#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ +#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 + +#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR +#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ + EXT3_FEATURE_INCOMPAT_META_BG) +#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) + +/* + * Default values for user and/or group using reserved blocks + */ +#define EXT3_DEF_RESUID 0 +#define EXT3_DEF_RESGID 0 + +/* + * Default mount options + */ +#define EXT3_DEFM_DEBUG 0x0001 +#define EXT3_DEFM_BSDGROUPS 0x0002 +#define EXT3_DEFM_XATTR_USER 0x0004 +#define EXT3_DEFM_ACL 0x0008 +#define EXT3_DEFM_UID16 0x0010 +#define EXT3_DEFM_JMODE 0x0060 +#define EXT3_DEFM_JMODE_DATA 0x0020 +#define EXT3_DEFM_JMODE_ORDERED 0x0040 +#define EXT3_DEFM_JMODE_WBACK 0x0060 + +/* + * Structure of a directory entry + */ +#define EXT3_NAME_LEN 255 + +struct ext3_dir_entry { + __le32 inode; /* Inode number */ + __le16 rec_len; /* Directory entry length */ + __le16 name_len; /* Name length */ + char name[EXT3_NAME_LEN]; /* File name */ +}; + +/* + * The new version of the directory entry. Since EXT3 structures are + * stored in intel byte order, and the name_len field could never be + * bigger than 255 chars, it's safe to reclaim the extra byte for the + * file_type field. + */ +struct ext3_dir_entry_2 { + __le32 inode; /* Inode number */ + __le16 rec_len; /* Directory entry length */ + __u8 name_len; /* Name length */ + __u8 file_type; + char name[EXT3_NAME_LEN]; /* File name */ +}; + +/* + * Ext3 directory file types. Only the low 3 bits are used. The + * other bits are reserved for now. + */ +#define EXT3_FT_UNKNOWN 0 +#define EXT3_FT_REG_FILE 1 +#define EXT3_FT_DIR 2 +#define EXT3_FT_CHRDEV 3 +#define EXT3_FT_BLKDEV 4 +#define EXT3_FT_FIFO 5 +#define EXT3_FT_SOCK 6 +#define EXT3_FT_SYMLINK 7 + +#define EXT3_FT_MAX 8 + +/* + * EXT3_DIR_PAD defines the directory entries boundaries + * + * NOTE: It must be a multiple of 4 + */ +#define EXT3_DIR_PAD 4 +#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) +#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ + ~EXT3_DIR_ROUND) +#define EXT3_MAX_REC_LEN ((1<<16)-1) + +/* + * Tests against MAX_REC_LEN etc were put in place for 64k block + * sizes; if that is not possible on this arch, we can skip + * those tests and speed things up. + */ +static inline unsigned ext3_rec_len_from_disk(__le16 dlen) +{ + unsigned len = le16_to_cpu(dlen); + +#if (PAGE_CACHE_SIZE >= 65536) + if (len == EXT3_MAX_REC_LEN) + return 1 << 16; +#endif + return len; +} + +static inline __le16 ext3_rec_len_to_disk(unsigned len) +{ +#if (PAGE_CACHE_SIZE >= 65536) + if (len == (1 << 16)) + return cpu_to_le16(EXT3_MAX_REC_LEN); + else if (len > (1 << 16)) + BUG(); +#endif + return cpu_to_le16(len); +} + +/* + * Hash Tree Directory indexing + * (c) Daniel Phillips, 2001 + */ + +#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ + EXT3_FEATURE_COMPAT_DIR_INDEX) && \ + (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) +#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) +#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) + +/* Legal values for the dx_root hash_version field: */ + +#define DX_HASH_LEGACY 0 +#define DX_HASH_HALF_MD4 1 +#define DX_HASH_TEA 2 +#define DX_HASH_LEGACY_UNSIGNED 3 +#define DX_HASH_HALF_MD4_UNSIGNED 4 +#define DX_HASH_TEA_UNSIGNED 5 + +/* hash info structure used by the directory hash */ +struct dx_hash_info +{ + u32 hash; + u32 minor_hash; + int hash_version; + u32 *seed; +}; + +#define EXT3_HTREE_EOF 0x7fffffff + +/* + * Control parameters used by ext3_htree_next_block + */ +#define HASH_NB_ALWAYS 1 + + +/* + * Describe an inode's exact location on disk and in memory + */ +struct ext3_iloc +{ + struct buffer_head *bh; + unsigned long offset; + unsigned long block_group; +}; + +static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc) +{ + return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset); +} + +/* + * This structure is stuffed into the struct file's private_data field + * for directories. It is where we put information so that we can do + * readdir operations in hash tree order. + */ +struct dir_private_info { + struct rb_root root; + struct rb_node *curr_node; + struct fname *extra_fname; + loff_t last_pos; + __u32 curr_hash; + __u32 curr_minor_hash; + __u32 next_hash; +}; + +/* calculate the first block number of the group */ +static inline ext3_fsblk_t +ext3_group_first_block_no(struct super_block *sb, unsigned long group_no) +{ + return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) + + le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); +} + +/* + * Special error return code only used by dx_probe() and its callers. + */ +#define ERR_BAD_DX_DIR -75000 + +/* + * Function prototypes + */ + +/* + * Ok, these declarations are also in but none of the + * ext3 source programs needs to include it so they are duplicated here. + */ +# define NORET_TYPE /**/ +# define ATTRIB_NORET __attribute__((noreturn)) +# define NORET_AND noreturn, + +/* balloc.c */ +extern int ext3_bg_has_super(struct super_block *sb, int group); +extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); +extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode, + ext3_fsblk_t goal, int *errp); +extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode, + ext3_fsblk_t goal, unsigned long *count, int *errp); +extern void ext3_free_blocks (handle_t *handle, struct inode *inode, + ext3_fsblk_t block, unsigned long count); +extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb, + ext3_fsblk_t block, unsigned long count, + unsigned long *pdquot_freed_blocks); +extern ext3_fsblk_t ext3_count_free_blocks (struct super_block *); +extern void ext3_check_blocks_bitmap (struct super_block *); +extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, + unsigned int block_group, + struct buffer_head ** bh); +extern int ext3_should_retry_alloc(struct super_block *sb, int *retries); +extern void ext3_init_block_alloc_info(struct inode *); +extern void ext3_rsv_window_add(struct super_block *sb, struct ext3_reserve_window_node *rsv); +extern int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range); + +/* dir.c */ +extern int ext3_check_dir_entry(const char *, struct inode *, + struct ext3_dir_entry_2 *, + struct buffer_head *, unsigned long); +extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, + __u32 minor_hash, + struct ext3_dir_entry_2 *dirent); +extern void ext3_htree_free_dir_info(struct dir_private_info *p); + +/* fsync.c */ +extern int ext3_sync_file(struct file *, loff_t, loff_t, int); + +/* hash.c */ +extern int ext3fs_dirhash(const char *name, int len, struct + dx_hash_info *hinfo); + +/* ialloc.c */ +extern struct inode * ext3_new_inode (handle_t *, struct inode *, + const struct qstr *, umode_t); +extern void ext3_free_inode (handle_t *, struct inode *); +extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); +extern unsigned long ext3_count_free_inodes (struct super_block *); +extern unsigned long ext3_count_dirs (struct super_block *); +extern void ext3_check_inodes_bitmap (struct super_block *); +extern unsigned long ext3_count_free (struct buffer_head *, unsigned); + + +/* inode.c */ +int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, + struct buffer_head *bh, ext3_fsblk_t blocknr); +struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); +struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); +int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, + int create); + +extern struct inode *ext3_iget(struct super_block *, unsigned long); +extern int ext3_write_inode (struct inode *, struct writeback_control *); +extern int ext3_setattr (struct dentry *, struct iattr *); +extern void ext3_evict_inode (struct inode *); +extern int ext3_sync_inode (handle_t *, struct inode *); +extern void ext3_discard_reservation (struct inode *); +extern void ext3_dirty_inode(struct inode *, int); +extern int ext3_change_inode_journal_flag(struct inode *, int); +extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); +extern int ext3_can_truncate(struct inode *inode); +extern void ext3_truncate(struct inode *inode); +extern void ext3_set_inode_flags(struct inode *); +extern void ext3_get_inode_flags(struct ext3_inode_info *); +extern void ext3_set_aops(struct inode *inode); +extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len); + +/* ioctl.c */ +extern long ext3_ioctl(struct file *, unsigned int, unsigned long); +extern long ext3_compat_ioctl(struct file *, unsigned int, unsigned long); + +/* namei.c */ +extern int ext3_orphan_add(handle_t *, struct inode *); +extern int ext3_orphan_del(handle_t *, struct inode *); +extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, + __u32 start_minor_hash, __u32 *next_hash); + +/* resize.c */ +extern int ext3_group_add(struct super_block *sb, + struct ext3_new_group_data *input); +extern int ext3_group_extend(struct super_block *sb, + struct ext3_super_block *es, + ext3_fsblk_t n_blocks_count); + +/* super.c */ +extern __printf(3, 4) +void ext3_error(struct super_block *, const char *, const char *, ...); +extern void __ext3_std_error (struct super_block *, const char *, int); +extern __printf(3, 4) +void ext3_abort(struct super_block *, const char *, const char *, ...); +extern __printf(3, 4) +void ext3_warning(struct super_block *, const char *, const char *, ...); +extern __printf(3, 4) +void ext3_msg(struct super_block *, const char *, const char *, ...); +extern void ext3_update_dynamic_rev (struct super_block *sb); + +#define ext3_std_error(sb, errno) \ +do { \ + if ((errno)) \ + __ext3_std_error((sb), __func__, (errno)); \ +} while (0) + +/* + * Inodes and files operations + */ + +/* dir.c */ +extern const struct file_operations ext3_dir_operations; + +/* file.c */ +extern const struct inode_operations ext3_file_inode_operations; +extern const struct file_operations ext3_file_operations; + +/* namei.c */ +extern const struct inode_operations ext3_dir_inode_operations; +extern const struct inode_operations ext3_special_inode_operations; + +/* symlink.c */ +extern const struct inode_operations ext3_symlink_inode_operations; +extern const struct inode_operations ext3_fast_symlink_inode_operations; + +#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) + +/* Define the number of blocks we need to account to a transaction to + * modify one block of data. + * + * We may have to touch one inode, one bitmap buffer, up to three + * indirection blocks, the group and superblock summaries, and the data + * block to complete the transaction. */ + +#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U + +/* Extended attribute operations touch at most two data buffers, + * two bitmap buffers, and two group summaries, in addition to the inode + * and the superblock, which are already accounted for. */ + +#define EXT3_XATTR_TRANS_BLOCKS 6U + +/* Define the minimum size for a transaction which modifies data. This + * needs to take into account the fact that we may end up modifying two + * quota files too (one for the group, one for the user quota). The + * superblock only gets updated once, of course, so don't bother + * counting that again for the quota updates. */ + +#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ + EXT3_XATTR_TRANS_BLOCKS - 2 + \ + EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) + +/* Delete operations potentially hit one directory's namespace plus an + * entire inode, plus arbitrary amounts of bitmap/indirection data. Be + * generous. We can grow the delete transaction later if necessary. */ + +#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) + +/* Define an arbitrary limit for the amount of data we will anticipate + * writing to any given transaction. For unbounded transactions such as + * write(2) and truncate(2) we can write more than this, but we always + * start off at the maximum transaction size and grow the transaction + * optimistically as we go. */ + +#define EXT3_MAX_TRANS_DATA 64U + +/* We break up a large truncate or write transaction once the handle's + * buffer credits gets this low, we need either to extend the + * transaction or to start a new one. Reserve enough space here for + * inode, bitmap, superblock, group and indirection updates for at least + * one block, plus two quota updates. Quota allocations are not + * needed. */ + +#define EXT3_RESERVE_TRANS_BLOCKS 12U + +#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 + +#ifdef CONFIG_QUOTA +/* Amount of blocks needed for quota update - we know that the structure was + * allocated so we need to update only inode+data */ +#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) +/* Amount of blocks needed for quota insert/delete - we do some block writes + * but inode, sb and group updates are done only once */ +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) +#else +#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 +#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 +#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 +#endif +#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) + +int +ext3_mark_iloc_dirty(handle_t *handle, + struct inode *inode, + struct ext3_iloc *iloc); + +/* + * On success, We end up with an outstanding reference count against + * iloc->bh. This _must_ be cleaned up later. + */ + +int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, + struct ext3_iloc *iloc); + +int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); + +/* + * Wrapper functions with which ext3 calls into JBD. The intent here is + * to allow these to be turned into appropriate stubs so ext3 can control + * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't + * been done yet. + */ + +static inline void ext3_journal_release_buffer(handle_t *handle, + struct buffer_head *bh) +{ + journal_release_buffer(handle, bh); +} + +void ext3_journal_abort_handle(const char *caller, const char *err_fn, + struct buffer_head *bh, handle_t *handle, int err); + +int __ext3_journal_get_undo_access(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_get_write_access(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_forget(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_revoke(const char *where, handle_t *handle, + unsigned long blocknr, struct buffer_head *bh); + +int __ext3_journal_get_create_access(const char *where, + handle_t *handle, struct buffer_head *bh); + +int __ext3_journal_dirty_metadata(const char *where, + handle_t *handle, struct buffer_head *bh); + +#define ext3_journal_get_undo_access(handle, bh) \ + __ext3_journal_get_undo_access(__func__, (handle), (bh)) +#define ext3_journal_get_write_access(handle, bh) \ + __ext3_journal_get_write_access(__func__, (handle), (bh)) +#define ext3_journal_revoke(handle, blocknr, bh) \ + __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) +#define ext3_journal_get_create_access(handle, bh) \ + __ext3_journal_get_create_access(__func__, (handle), (bh)) +#define ext3_journal_dirty_metadata(handle, bh) \ + __ext3_journal_dirty_metadata(__func__, (handle), (bh)) +#define ext3_journal_forget(handle, bh) \ + __ext3_journal_forget(__func__, (handle), (bh)) + +int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); + +handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); +int __ext3_journal_stop(const char *where, handle_t *handle); + +static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) +{ + return ext3_journal_start_sb(inode->i_sb, nblocks); +} + +#define ext3_journal_stop(handle) \ + __ext3_journal_stop(__func__, (handle)) + +static inline handle_t *ext3_journal_current_handle(void) +{ + return journal_current_handle(); +} + +static inline int ext3_journal_extend(handle_t *handle, int nblocks) +{ + return journal_extend(handle, nblocks); +} + +static inline int ext3_journal_restart(handle_t *handle, int nblocks) +{ + return journal_restart(handle, nblocks); +} + +static inline int ext3_journal_blocks_per_page(struct inode *inode) +{ + return journal_blocks_per_page(inode); +} + +static inline int ext3_journal_force_commit(journal_t *journal) +{ + return journal_force_commit(journal); +} + +/* super.c */ +int ext3_force_commit(struct super_block *sb); + +static inline int ext3_should_journal_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 1; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) + return 1; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 1; + return 0; +} + +static inline int ext3_should_order_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) + return 1; + return 0; +} + +static inline int ext3_should_writeback_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) + return 1; + return 0; +} + +#include + diff --git a/instrumentation/events/mainline/gpio.h b/instrumentation/events/mainline/gpio.h new file mode 100644 index 0000000..927a8ad --- /dev/null +++ b/instrumentation/events/mainline/gpio.h @@ -0,0 +1,56 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM gpio + +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_GPIO_H + +#include + +TRACE_EVENT(gpio_direction, + + TP_PROTO(unsigned gpio, int in, int err), + + TP_ARGS(gpio, in, err), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, in) + __field(int, err) + ), + + TP_fast_assign( + __entry->gpio = gpio; + __entry->in = in; + __entry->err = err; + ), + + TP_printk("%u %3s (%d)", __entry->gpio, + __entry->in ? "in" : "out", __entry->err) +); + +TRACE_EVENT(gpio_value, + + TP_PROTO(unsigned gpio, int get, int value), + + TP_ARGS(gpio, get, value), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, get) + __field(int, value) + ), + + TP_fast_assign( + __entry->gpio = gpio; + __entry->get = get; + __entry->value = value; + ), + + TP_printk("%u %3s %d", __entry->gpio, + __entry->get ? "get" : "set", __entry->value) +); + +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/jbd.h b/instrumentation/events/mainline/jbd.h new file mode 100644 index 0000000..aff64d8 --- /dev/null +++ b/instrumentation/events/mainline/jbd.h @@ -0,0 +1,203 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd + +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD_H + +#include +#include + +TRACE_EVENT(jbd_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->result = result; + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->result) +); + +DECLARE_EVENT_CLASS(jbd_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +DEFINE_EVENT(jbd_commit, jbd_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd_commit, jbd_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd_commit, jbd_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +TRACE_EVENT(jbd_drop_transaction, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +TRACE_EVENT(jbd_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + __entry->head = journal->j_tail_sequence; + ), + + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +); + +TRACE_EVENT(jbd_do_submit_data, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +TRACE_EVENT(jbd_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->tail_sequence = journal->j_tail_sequence; + __entry->first_tid = first_tid; + __entry->block_nr = block_nr; + __entry->freed = freed; + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +); + +TRACE_EVENT(jbd_update_superblock_end, + TP_PROTO(journal_t *journal, int wait), + + TP_ARGS(journal, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->wait = wait; + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +); + +#endif /* _TRACE_JBD_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/jbd2.h b/instrumentation/events/mainline/jbd2.h new file mode 100644 index 0000000..7596441 --- /dev/null +++ b/instrumentation/events/mainline/jbd2.h @@ -0,0 +1,235 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd2 + +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD2_H + +#include +#include + +struct transaction_chp_stats_s; +struct transaction_run_stats_s; + +TRACE_EVENT(jbd2_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->result = result; + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) +); + +DECLARE_EVENT_CLASS(jbd2_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +TRACE_EVENT(jbd2_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + __entry->head = journal->j_tail_sequence; + ), + + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +); + +TRACE_EVENT(jbd2_submit_inode_data, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +); + +TRACE_EVENT(jbd2_run_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_run_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, wait ) + __field( unsigned long, running ) + __field( unsigned long, locked ) + __field( unsigned long, flushing ) + __field( unsigned long, logging ) + __field( __u32, handle_count ) + __field( __u32, blocks ) + __field( __u32, blocks_logged ) + ), + + TP_fast_assign( + __entry->dev = dev; + __entry->tid = tid; + __entry->wait = stats->rs_wait; + __entry->running = stats->rs_running; + __entry->locked = stats->rs_locked; + __entry->flushing = stats->rs_flushing; + __entry->logging = stats->rs_logging; + __entry->handle_count = stats->rs_handle_count; + __entry->blocks = stats->rs_blocks; + __entry->blocks_logged = stats->rs_blocks_logged; + ), + + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " + "logging %u handle_count %u blocks %u blocks_logged %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->wait), + jiffies_to_msecs(__entry->running), + jiffies_to_msecs(__entry->locked), + jiffies_to_msecs(__entry->flushing), + jiffies_to_msecs(__entry->logging), + __entry->handle_count, __entry->blocks, + __entry->blocks_logged) +); + +TRACE_EVENT(jbd2_checkpoint_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_chp_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, chp_time ) + __field( __u32, forced_to_close ) + __field( __u32, written ) + __field( __u32, dropped ) + ), + + TP_fast_assign( + __entry->dev = dev; + __entry->tid = tid; + __entry->chp_time = stats->cs_chp_time; + __entry->forced_to_close= stats->cs_forced_to_close; + __entry->written = stats->cs_written; + __entry->dropped = stats->cs_dropped; + ), + + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " + "written %u dropped %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->chp_time), + __entry->forced_to_close, __entry->written, __entry->dropped) +); + +TRACE_EVENT(jbd2_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->tail_sequence = journal->j_tail_sequence; + __entry->first_tid = first_tid; + __entry->block_nr = block_nr; + __entry->freed = freed; + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +); + +#endif /* _TRACE_JBD2_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/kmem.h b/instrumentation/events/mainline/kmem.h new file mode 100644 index 0000000..a9c87ad --- /dev/null +++ b/instrumentation/events/mainline/kmem.h @@ -0,0 +1,308 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kmem + +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KMEM_H + +#include +#include +#include "gfpflags.h" + +DECLARE_EVENT_CLASS(kmem_alloc, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags)) +); + +DEFINE_EVENT(kmem_alloc, kmalloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +); + +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +); + +DECLARE_EVENT_CLASS(kmem_alloc_node, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags, + int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + __field( int, node ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + __entry->node = node; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags), + __entry->node) +); + +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +); + +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +); + +DECLARE_EVENT_CLASS(kmem_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + ), + + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) +); + +DEFINE_EVENT(kmem_free, kfree, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +); + +DEFINE_EVENT(kmem_free, kmem_cache_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +); + +TRACE_EVENT(mm_page_free_direct, + + TP_PROTO(struct page *page, unsigned int order), + + TP_ARGS(page, order), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->order = order; + ), + + TP_printk("page=%p pfn=%lu order=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order) +); + +TRACE_EVENT(mm_pagevec_free, + + TP_PROTO(struct page *page, int cold), + + TP_ARGS(page, cold), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, cold ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->cold = cold; + ), + + TP_printk("page=%p pfn=%lu order=0 cold=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->cold) +); + +TRACE_EVENT(mm_page_alloc, + + TP_PROTO(struct page *page, unsigned int order, + gfp_t gfp_flags, int migratetype), + + TP_ARGS(page, order, gfp_flags, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( gfp_t, gfp_flags ) + __field( int, migratetype ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->order = order; + __entry->gfp_flags = gfp_flags; + __entry->migratetype = migratetype; + ), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + show_gfp_flags(__entry->gfp_flags)) +); + +DECLARE_EVENT_CLASS(mm_page, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( int, migratetype ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->order = order; + __entry->migratetype = migratetype; + ), + + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + __entry->order == 0) +); + +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype) +); + +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", + __entry->page, page_to_pfn(__entry->page), + __entry->order, __entry->migratetype) +); + +TRACE_EVENT(mm_page_alloc_extfrag, + + TP_PROTO(struct page *page, + int alloc_order, int fallback_order, + int alloc_migratetype, int fallback_migratetype), + + TP_ARGS(page, + alloc_order, fallback_order, + alloc_migratetype, fallback_migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, alloc_order ) + __field( int, fallback_order ) + __field( int, alloc_migratetype ) + __field( int, fallback_migratetype ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->alloc_order = alloc_order; + __entry->fallback_order = fallback_order; + __entry->alloc_migratetype = alloc_migratetype; + __entry->fallback_migratetype = fallback_migratetype; + ), + + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->alloc_order, + __entry->fallback_order, + pageblock_order, + __entry->alloc_migratetype, + __entry->fallback_migratetype, + __entry->fallback_order < pageblock_order, + __entry->alloc_migratetype == __entry->fallback_migratetype) +); + +#endif /* _TRACE_KMEM_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/lock.h b/instrumentation/events/mainline/lock.h new file mode 100644 index 0000000..2821b86 --- /dev/null +++ b/instrumentation/events/mainline/lock.h @@ -0,0 +1,86 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lock + +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_LOCK_H + +#include +#include + +#ifdef CONFIG_LOCKDEP + +TRACE_EVENT(lock_acquire, + + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, + struct lockdep_map *next_lock, unsigned long ip), + + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), + + TP_STRUCT__entry( + __field(unsigned int, flags) + __string(name, lock->name) + __field(void *, lockdep_addr) + ), + + TP_fast_assign( + __entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0); + __assign_str(name, lock->name); + __entry->lockdep_addr = lock; + ), + + TP_printk("%p %s%s%s", __entry->lockdep_addr, + (__entry->flags & 1) ? "try " : "", + (__entry->flags & 2) ? "read " : "", + __get_str(name)) +); + +DECLARE_EVENT_CLASS(lock, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip), + + TP_STRUCT__entry( + __string( name, lock->name ) + __field( void *, lockdep_addr ) + ), + + TP_fast_assign( + __assign_str(name, lock->name); + __entry->lockdep_addr = lock; + ), + + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) +); + +DEFINE_EVENT(lock, lock_release, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +); + +#ifdef CONFIG_LOCK_STAT + +DEFINE_EVENT(lock, lock_contended, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +); + +DEFINE_EVENT(lock, lock_acquired, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +); + +#endif +#endif + +#endif /* _TRACE_LOCK_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/module.h b/instrumentation/events/mainline/module.h new file mode 100644 index 0000000..21a546d --- /dev/null +++ b/instrumentation/events/mainline/module.h @@ -0,0 +1,131 @@ +/* + * Because linux/module.h has tracepoints in the header, and ftrace.h + * eventually includes this file, define_trace.h includes linux/module.h + * But we do not want the module.h to override the TRACE_SYSTEM macro + * variable that define_trace.h is processing, so we only set it + * when module events are being processed, which would happen when + * CREATE_TRACE_POINTS is defined. + */ +#ifdef CREATE_TRACE_POINTS +#undef TRACE_SYSTEM +#define TRACE_SYSTEM module +#endif + +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MODULE_H + +#include + +#ifdef CONFIG_MODULES + +struct module; + +#define show_module_flags(flags) __print_flags(flags, "", \ + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ + { (1UL << TAINT_FORCED_MODULE), "F" }, \ + { (1UL << TAINT_CRAP), "C" }) + +TRACE_EVENT(module_load, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __field( unsigned int, taints ) + __string( name, mod->name ) + ), + + TP_fast_assign( + __entry->taints = mod->taints; + __assign_str(name, mod->name); + ), + + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) +); + +TRACE_EVENT(module_free, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __string( name, mod->name ) + ), + + TP_fast_assign( + __assign_str(name, mod->name); + ), + + TP_printk("%s", __get_str(name)) +); + +#ifdef CONFIG_MODULE_UNLOAD +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ + +DECLARE_EVENT_CLASS(module_refcnt, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( int, refcnt ) + __string( name, mod->name ) + ), + + TP_fast_assign( + __entry->ip = ip; + __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs); + __assign_str(name, mod->name); + ), + + TP_printk("%s call_site=%pf refcnt=%d", + __get_str(name), (void *)__entry->ip, __entry->refcnt) +); + +DEFINE_EVENT(module_refcnt, module_get, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +); + +DEFINE_EVENT(module_refcnt, module_put, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +); +#endif /* CONFIG_MODULE_UNLOAD */ + +TRACE_EVENT(module_request, + + TP_PROTO(char *name, bool wait, unsigned long ip), + + TP_ARGS(name, wait, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( bool, wait ) + __string( name, name ) + ), + + TP_fast_assign( + __entry->ip = ip; + __entry->wait = wait; + __assign_str(name, name); + ), + + TP_printk("%s wait=%d call_site=%pf", + __get_str(name), (int)__entry->wait, (void *)__entry->ip) +); + +#endif /* CONFIG_MODULES */ + +#endif /* _TRACE_MODULE_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/napi.h b/instrumentation/events/mainline/napi.h new file mode 100644 index 0000000..8fe1e93 --- /dev/null +++ b/instrumentation/events/mainline/napi.h @@ -0,0 +1,38 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM napi + +#if !defined(_TRACE_NAPI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NAPI_H_ + +#include +#include +#include + +#define NO_DEV "(no_device)" + +TRACE_EVENT(napi_poll, + + TP_PROTO(struct napi_struct *napi), + + TP_ARGS(napi), + + TP_STRUCT__entry( + __field( struct napi_struct *, napi) + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) + ), + + TP_fast_assign( + __entry->napi = napi; + __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV); + ), + + TP_printk("napi poll on napi struct %p for device %s", + __entry->napi, __get_str(dev_name)) +); + +#undef NO_DEV + +#endif /* _TRACE_NAPI_H_ */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/net.h b/instrumentation/events/mainline/net.h new file mode 100644 index 0000000..f99645d --- /dev/null +++ b/instrumentation/events/mainline/net.h @@ -0,0 +1,84 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM net + +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NET_H + +#include +#include +#include +#include + +TRACE_EVENT(net_dev_xmit, + + TP_PROTO(struct sk_buff *skb, + int rc, + struct net_device *dev, + unsigned int skb_len), + + TP_ARGS(skb, rc, dev, skb_len), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __field( int, rc ) + __string( name, dev->name ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->len = skb_len; + __entry->rc = rc; + __assign_str(name, dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) +); + +DECLARE_EVENT_CLASS(net_dev_template, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __string( name, skb->dev->name ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->len = skb->len; + __assign_str(name, skb->dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u", + __get_str(name), __entry->skbaddr, __entry->len) +) + +DEFINE_EVENT(net_dev_template, net_dev_queue, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +); + +DEFINE_EVENT(net_dev_template, netif_receive_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +); + +DEFINE_EVENT(net_dev_template, netif_rx, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +); +#endif /* _TRACE_NET_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/power.h b/instrumentation/events/mainline/power.h new file mode 100644 index 0000000..1bcc2a8 --- /dev/null +++ b/instrumentation/events/mainline/power.h @@ -0,0 +1,240 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM power + +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_POWER_H + +#include +#include + +DECLARE_EVENT_CLASS(cpu, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id), + + TP_STRUCT__entry( + __field( u32, state ) + __field( u32, cpu_id ) + ), + + TP_fast_assign( + __entry->state = state; + __entry->cpu_id = cpu_id; + ), + + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, + (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(cpu, cpu_idle, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id) +); + +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING + +#define PWR_EVENT_EXIT -1 +#endif + +DEFINE_EVENT(cpu, cpu_frequency, + + TP_PROTO(unsigned int frequency, unsigned int cpu_id), + + TP_ARGS(frequency, cpu_id) +); + +TRACE_EVENT(machine_suspend, + + TP_PROTO(unsigned int state), + + TP_ARGS(state), + + TP_STRUCT__entry( + __field( u32, state ) + ), + + TP_fast_assign( + __entry->state = state; + ), + + TP_printk("state=%lu", (unsigned long)__entry->state) +); + +/* This code will be removed after deprecation time exceeded (2.6.41) */ +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED + +/* + * The power events are used for cpuidle & suspend (power_start, power_end) + * and for cpufreq (power_frequency) + */ +DECLARE_EVENT_CLASS(power, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id), + + TP_STRUCT__entry( + __field( u64, type ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __entry->type = type; + __entry->state = state; + __entry->cpu_id = cpu_id; + ), + + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(power, power_start, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +); + +DEFINE_EVENT(power, power_frequency, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +); + +TRACE_EVENT(power_end, + + TP_PROTO(unsigned int cpu_id), + + TP_ARGS(cpu_id), + + TP_STRUCT__entry( + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __entry->cpu_id = cpu_id; + ), + + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) + +); + +/* Deprecated dummy functions must be protected against multi-declartion */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED + +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; + +/* These dummy declaration have to be ripped out when the deprecated + events get removed */ +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; +static inline void trace_power_end(u64 cpuid) {}; +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +/* + * The clock events are used for clock enable/disable and for + * clock rate change + */ +DECLARE_EVENT_CLASS(clock, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->state = state; + __entry->cpu_id = cpu_id; + ), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(clock, clock_enable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); + +DEFINE_EVENT(clock, clock_disable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); + +DEFINE_EVENT(clock, clock_set_rate, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); + +/* + * The power domain events are used for power domains transitions + */ +DECLARE_EVENT_CLASS(power_domain, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->state = state; + __entry->cpu_id = cpu_id; +), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(power_domain, power_domain_target, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/regulator.h b/instrumentation/events/mainline/regulator.h new file mode 100644 index 0000000..37502a7 --- /dev/null +++ b/instrumentation/events/mainline/regulator.h @@ -0,0 +1,141 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM regulator + +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_REGULATOR_H + +#include +#include + +/* + * Events which just log themselves and the regulator name for enable/disable + * type tracking. + */ +DECLARE_EVENT_CLASS(regulator_basic, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + __assign_str(name, name); + ), + + TP_printk("name=%s", __get_str(name)) + +); + +DEFINE_EVENT(regulator_basic, regulator_enable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_enable_delay, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_enable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_disable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_disable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +/* + * Events that take a range of numerical values, mostly for voltages + * and so on. + */ +DECLARE_EVENT_CLASS(regulator_range, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max), + + TP_STRUCT__entry( + __string( name, name ) + __field( int, min ) + __field( int, max ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->min = min; + __entry->max = max; + ), + + TP_printk("name=%s (%d-%d)", __get_str(name), + (int)__entry->min, (int)__entry->max) +); + +DEFINE_EVENT(regulator_range, regulator_set_voltage, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max) + +); + + +/* + * Events that take a single value, mostly for readback and refcounts. + */ +DECLARE_EVENT_CLASS(regulator_value, + + TP_PROTO(const char *name, unsigned int val), + + TP_ARGS(name, val), + + TP_STRUCT__entry( + __string( name, name ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->val = val; + ), + + TP_printk("name=%s, val=%u", __get_str(name), + (int)__entry->val) +); + +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, + + TP_PROTO(const char *name, unsigned int value), + + TP_ARGS(name, value) + +); + +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/scsi.h b/instrumentation/events/mainline/scsi.h new file mode 100644 index 0000000..db6c935 --- /dev/null +++ b/instrumentation/events/mainline/scsi.h @@ -0,0 +1,365 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM scsi + +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SCSI_H + +#include +#include +#include +#include + +#define scsi_opcode_name(opcode) { opcode, #opcode } +#define show_opcode_name(val) \ + __print_symbolic(val, \ + scsi_opcode_name(TEST_UNIT_READY), \ + scsi_opcode_name(REZERO_UNIT), \ + scsi_opcode_name(REQUEST_SENSE), \ + scsi_opcode_name(FORMAT_UNIT), \ + scsi_opcode_name(READ_BLOCK_LIMITS), \ + scsi_opcode_name(REASSIGN_BLOCKS), \ + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ + scsi_opcode_name(READ_6), \ + scsi_opcode_name(WRITE_6), \ + scsi_opcode_name(SEEK_6), \ + scsi_opcode_name(READ_REVERSE), \ + scsi_opcode_name(WRITE_FILEMARKS), \ + scsi_opcode_name(SPACE), \ + scsi_opcode_name(INQUIRY), \ + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ + scsi_opcode_name(MODE_SELECT), \ + scsi_opcode_name(RESERVE), \ + scsi_opcode_name(RELEASE), \ + scsi_opcode_name(COPY), \ + scsi_opcode_name(ERASE), \ + scsi_opcode_name(MODE_SENSE), \ + scsi_opcode_name(START_STOP), \ + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ + scsi_opcode_name(SEND_DIAGNOSTIC), \ + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ + scsi_opcode_name(SET_WINDOW), \ + scsi_opcode_name(READ_CAPACITY), \ + scsi_opcode_name(READ_10), \ + scsi_opcode_name(WRITE_10), \ + scsi_opcode_name(SEEK_10), \ + scsi_opcode_name(POSITION_TO_ELEMENT), \ + scsi_opcode_name(WRITE_VERIFY), \ + scsi_opcode_name(VERIFY), \ + scsi_opcode_name(SEARCH_HIGH), \ + scsi_opcode_name(SEARCH_EQUAL), \ + scsi_opcode_name(SEARCH_LOW), \ + scsi_opcode_name(SET_LIMITS), \ + scsi_opcode_name(PRE_FETCH), \ + scsi_opcode_name(READ_POSITION), \ + scsi_opcode_name(SYNCHRONIZE_CACHE), \ + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ + scsi_opcode_name(READ_DEFECT_DATA), \ + scsi_opcode_name(MEDIUM_SCAN), \ + scsi_opcode_name(COMPARE), \ + scsi_opcode_name(COPY_VERIFY), \ + scsi_opcode_name(WRITE_BUFFER), \ + scsi_opcode_name(READ_BUFFER), \ + scsi_opcode_name(UPDATE_BLOCK), \ + scsi_opcode_name(READ_LONG), \ + scsi_opcode_name(WRITE_LONG), \ + scsi_opcode_name(CHANGE_DEFINITION), \ + scsi_opcode_name(WRITE_SAME), \ + scsi_opcode_name(UNMAP), \ + scsi_opcode_name(READ_TOC), \ + scsi_opcode_name(LOG_SELECT), \ + scsi_opcode_name(LOG_SENSE), \ + scsi_opcode_name(XDWRITEREAD_10), \ + scsi_opcode_name(MODE_SELECT_10), \ + scsi_opcode_name(RESERVE_10), \ + scsi_opcode_name(RELEASE_10), \ + scsi_opcode_name(MODE_SENSE_10), \ + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ + scsi_opcode_name(REPORT_LUNS), \ + scsi_opcode_name(MAINTENANCE_IN), \ + scsi_opcode_name(MAINTENANCE_OUT), \ + scsi_opcode_name(MOVE_MEDIUM), \ + scsi_opcode_name(EXCHANGE_MEDIUM), \ + scsi_opcode_name(READ_12), \ + scsi_opcode_name(WRITE_12), \ + scsi_opcode_name(WRITE_VERIFY_12), \ + scsi_opcode_name(SEARCH_HIGH_12), \ + scsi_opcode_name(SEARCH_EQUAL_12), \ + scsi_opcode_name(SEARCH_LOW_12), \ + scsi_opcode_name(READ_ELEMENT_STATUS), \ + scsi_opcode_name(SEND_VOLUME_TAG), \ + scsi_opcode_name(WRITE_LONG_2), \ + scsi_opcode_name(READ_16), \ + scsi_opcode_name(WRITE_16), \ + scsi_opcode_name(VERIFY_16), \ + scsi_opcode_name(WRITE_SAME_16), \ + scsi_opcode_name(SERVICE_ACTION_IN), \ + scsi_opcode_name(SAI_READ_CAPACITY_16), \ + scsi_opcode_name(SAI_GET_LBA_STATUS), \ + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ + scsi_opcode_name(MO_SET_TARGET_PGS), \ + scsi_opcode_name(READ_32), \ + scsi_opcode_name(WRITE_32), \ + scsi_opcode_name(WRITE_SAME_32), \ + scsi_opcode_name(ATA_16), \ + scsi_opcode_name(ATA_12)) + +#define scsi_hostbyte_name(result) { result, #result } +#define show_hostbyte_name(val) \ + __print_symbolic(val, \ + scsi_hostbyte_name(DID_OK), \ + scsi_hostbyte_name(DID_NO_CONNECT), \ + scsi_hostbyte_name(DID_BUS_BUSY), \ + scsi_hostbyte_name(DID_TIME_OUT), \ + scsi_hostbyte_name(DID_BAD_TARGET), \ + scsi_hostbyte_name(DID_ABORT), \ + scsi_hostbyte_name(DID_PARITY), \ + scsi_hostbyte_name(DID_ERROR), \ + scsi_hostbyte_name(DID_RESET), \ + scsi_hostbyte_name(DID_BAD_INTR), \ + scsi_hostbyte_name(DID_PASSTHROUGH), \ + scsi_hostbyte_name(DID_SOFT_ERROR), \ + scsi_hostbyte_name(DID_IMM_RETRY), \ + scsi_hostbyte_name(DID_REQUEUE), \ + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) + +#define scsi_driverbyte_name(result) { result, #result } +#define show_driverbyte_name(val) \ + __print_symbolic(val, \ + scsi_driverbyte_name(DRIVER_OK), \ + scsi_driverbyte_name(DRIVER_BUSY), \ + scsi_driverbyte_name(DRIVER_SOFT), \ + scsi_driverbyte_name(DRIVER_MEDIA), \ + scsi_driverbyte_name(DRIVER_ERROR), \ + scsi_driverbyte_name(DRIVER_INVALID), \ + scsi_driverbyte_name(DRIVER_TIMEOUT), \ + scsi_driverbyte_name(DRIVER_HARD), \ + scsi_driverbyte_name(DRIVER_SENSE)) + +#define scsi_msgbyte_name(result) { result, #result } +#define show_msgbyte_name(val) \ + __print_symbolic(val, \ + scsi_msgbyte_name(COMMAND_COMPLETE), \ + scsi_msgbyte_name(EXTENDED_MESSAGE), \ + scsi_msgbyte_name(SAVE_POINTERS), \ + scsi_msgbyte_name(RESTORE_POINTERS), \ + scsi_msgbyte_name(DISCONNECT), \ + scsi_msgbyte_name(INITIATOR_ERROR), \ + scsi_msgbyte_name(ABORT_TASK_SET), \ + scsi_msgbyte_name(MESSAGE_REJECT), \ + scsi_msgbyte_name(NOP), \ + scsi_msgbyte_name(MSG_PARITY_ERROR), \ + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ + scsi_msgbyte_name(TARGET_RESET), \ + scsi_msgbyte_name(ABORT_TASK), \ + scsi_msgbyte_name(CLEAR_TASK_SET), \ + scsi_msgbyte_name(INITIATE_RECOVERY), \ + scsi_msgbyte_name(RELEASE_RECOVERY), \ + scsi_msgbyte_name(CLEAR_ACA), \ + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ + scsi_msgbyte_name(ACA), \ + scsi_msgbyte_name(QAS_REQUEST), \ + scsi_msgbyte_name(BUS_DEVICE_RESET), \ + scsi_msgbyte_name(ABORT)) + +#define scsi_statusbyte_name(result) { result, #result } +#define show_statusbyte_name(val) \ + __print_symbolic(val, \ + scsi_statusbyte_name(SAM_STAT_GOOD), \ + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_BUSY), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) + +#define scsi_prot_op_name(result) { result, #result } +#define show_prot_op_name(val) \ + __print_symbolic(val, \ + scsi_prot_op_name(SCSI_PROT_NORMAL), \ + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) + +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) + +TRACE_EVENT(scsi_dispatch_cmd_start, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + __entry->host_no = cmd->device->host->host_no; + __entry->channel = cmd->device->channel; + __entry->id = cmd->device->id; + __entry->lun = cmd->device->lun; + __entry->opcode = cmd->cmnd[0]; + __entry->cmd_len = cmd->cmd_len; + __entry->data_sglen = scsi_sg_count(cmd); + __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) +); + +TRACE_EVENT(scsi_dispatch_cmd_error, + + TP_PROTO(struct scsi_cmnd *cmd, int rtn), + + TP_ARGS(cmd, rtn), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, rtn ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + __entry->host_no = cmd->device->host->host_no; + __entry->channel = cmd->device->channel; + __entry->id = cmd->device->id; + __entry->lun = cmd->device->lun; + __entry->rtn = rtn; + __entry->opcode = cmd->cmnd[0]; + __entry->cmd_len = cmd->cmd_len; + __entry->data_sglen = scsi_sg_count(cmd); + __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + __entry->rtn) +); + +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, result ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + __entry->host_no = cmd->device->host->host_no; + __entry->channel = cmd->device->channel; + __entry->id = cmd->device->id; + __entry->lun = cmd->device->lun; + __entry->result = cmd->result; + __entry->opcode = cmd->cmnd[0]; + __entry->cmd_len = cmd->cmd_len; + __entry->data_sglen = scsi_sg_count(cmd); + __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ + "%s host=%s message=%s status=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + show_driverbyte_name(((__entry->result) >> 24) & 0xff), + show_hostbyte_name(((__entry->result) >> 16) & 0xff), + show_msgbyte_name(((__entry->result) >> 8) & 0xff), + show_statusbyte_name(__entry->result & 0xff)) +); + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)); + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)); + +TRACE_EVENT(scsi_eh_wakeup, + + TP_PROTO(struct Scsi_Host *shost), + + TP_ARGS(shost), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + ), + + TP_fast_assign( + __entry->host_no = shost->host_no; + ), + + TP_printk("host_no=%u", __entry->host_no) +); + +#endif /* _TRACE_SCSI_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/skb.h b/instrumentation/events/mainline/skb.h new file mode 100644 index 0000000..0c68ae2 --- /dev/null +++ b/instrumentation/events/mainline/skb.h @@ -0,0 +1,75 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM skb + +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SKB_H + +#include +#include +#include + +/* + * Tracepoint for free an sk_buff: + */ +TRACE_EVENT(kfree_skb, + + TP_PROTO(struct sk_buff *skb, void *location), + + TP_ARGS(skb, location), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( void *, location ) + __field( unsigned short, protocol ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->location = location; + __entry->protocol = ntohs(skb->protocol); + ), + + TP_printk("skbaddr=%p protocol=%u location=%p", + __entry->skbaddr, __entry->protocol, __entry->location) +); + +TRACE_EVENT(consume_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + ), + + TP_printk("skbaddr=%p", __entry->skbaddr) +); + +TRACE_EVENT(skb_copy_datagram_iovec, + + TP_PROTO(const struct sk_buff *skb, int len), + + TP_ARGS(skb, len), + + TP_STRUCT__entry( + __field( const void *, skbaddr ) + __field( int, len ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->len = len; + ), + + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) +); + +#endif /* _TRACE_SKB_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/sock.h b/instrumentation/events/mainline/sock.h new file mode 100644 index 0000000..779abb9 --- /dev/null +++ b/instrumentation/events/mainline/sock.h @@ -0,0 +1,68 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sock + +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SOCK_H + +#include +#include + +TRACE_EVENT(sock_rcvqueue_full, + + TP_PROTO(struct sock *sk, struct sk_buff *skb), + + TP_ARGS(sk, skb), + + TP_STRUCT__entry( + __field(int, rmem_alloc) + __field(unsigned int, truesize) + __field(int, sk_rcvbuf) + ), + + TP_fast_assign( + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); + __entry->truesize = skb->truesize; + __entry->sk_rcvbuf = sk->sk_rcvbuf; + ), + + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) +); + +TRACE_EVENT(sock_exceed_buf_limit, + + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), + + TP_ARGS(sk, prot, allocated), + + TP_STRUCT__entry( + __array(char, name, 32) + __field(long *, sysctl_mem) + __field(long, allocated) + __field(int, sysctl_rmem) + __field(int, rmem_alloc) + ), + + TP_fast_assign( + strncpy(__entry->name, prot->name, 32); + __entry->sysctl_mem = prot->sysctl_mem; + __entry->allocated = allocated; + __entry->sysctl_rmem = prot->sysctl_rmem[0]; + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); + ), + + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " + "sysctl_rmem=%d rmem_alloc=%d", + __entry->name, + __entry->sysctl_mem[0], + __entry->sysctl_mem[1], + __entry->sysctl_mem[2], + __entry->allocated, + __entry->sysctl_rmem, + __entry->rmem_alloc) +); + +#endif /* _TRACE_SOCK_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/udp.h b/instrumentation/events/mainline/udp.h new file mode 100644 index 0000000..a664bb9 --- /dev/null +++ b/instrumentation/events/mainline/udp.h @@ -0,0 +1,32 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM udp + +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_UDP_H + +#include +#include + +TRACE_EVENT(udp_fail_queue_rcv_skb, + + TP_PROTO(int rc, struct sock *sk), + + TP_ARGS(rc, sk), + + TP_STRUCT__entry( + __field(int, rc) + __field(__u16, lport) + ), + + TP_fast_assign( + __entry->rc = rc; + __entry->lport = inet_sk(sk)->inet_num; + ), + + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) +); + +#endif /* _TRACE_UDP_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/vmscan.h b/instrumentation/events/mainline/vmscan.h new file mode 100644 index 0000000..36851f7 --- /dev/null +++ b/instrumentation/events/mainline/vmscan.h @@ -0,0 +1,477 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vmscan + +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_VMSCAN_H + +#include +#include +#include +#include +#include "gfpflags.h" + +#define RECLAIM_WB_ANON 0x0001u +#define RECLAIM_WB_FILE 0x0002u +#define RECLAIM_WB_MIXED 0x0010u +#define RECLAIM_WB_SYNC 0x0004u +#define RECLAIM_WB_ASYNC 0x0008u + +#define show_reclaim_flags(flags) \ + (flags) ? __print_flags(flags, "|", \ + {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ + {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ + {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ + {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ + {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ + ) : "RECLAIM_WB_NONE" + +#define trace_reclaim_flags(page, sync) ( \ + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + ) + +#define trace_shrink_flags(file, sync) ( \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + ) + +TRACE_EVENT(mm_vmscan_kswapd_sleep, + + TP_PROTO(int nid), + + TP_ARGS(nid), + + TP_STRUCT__entry( + __field( int, nid ) + ), + + TP_fast_assign( + __entry->nid = nid; + ), + + TP_printk("nid=%d", __entry->nid) +); + +TRACE_EVENT(mm_vmscan_kswapd_wake, + + TP_PROTO(int nid, int order), + + TP_ARGS(nid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, order ) + ), + + TP_fast_assign( + __entry->nid = nid; + __entry->order = order; + ), + + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) +); + +TRACE_EVENT(mm_vmscan_wakeup_kswapd, + + TP_PROTO(int nid, int zid, int order), + + TP_ARGS(nid, zid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, zid ) + __field( int, order ) + ), + + TP_fast_assign( + __entry->nid = nid; + __entry->zid = zid; + __entry->order = order; + ), + + TP_printk("nid=%d zid=%d order=%d", + __entry->nid, + __entry->zid, + __entry->order) +); + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags), + + TP_STRUCT__entry( + __field( int, order ) + __field( int, may_writepage ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + __entry->order = order; + __entry->may_writepage = may_writepage; + __entry->gfp_flags = gfp_flags; + ), + + TP_printk("order=%d may_writepage=%d gfp_flags=%s", + __entry->order, + __entry->may_writepage, + show_gfp_flags(__entry->gfp_flags)) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +); + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed), + + TP_STRUCT__entry( + __field( unsigned long, nr_reclaimed ) + ), + + TP_fast_assign( + __entry->nr_reclaimed = nr_reclaimed; + ), + + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +); + +TRACE_EVENT(mm_shrink_slab_start, + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, + long nr_objects_to_shrink, unsigned long pgs_scanned, + unsigned long lru_pgs, unsigned long cache_items, + unsigned long long delta, unsigned long total_scan), + + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, + cache_items, delta, total_scan), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, nr_objects_to_shrink) + __field(gfp_t, gfp_flags) + __field(unsigned long, pgs_scanned) + __field(unsigned long, lru_pgs) + __field(unsigned long, cache_items) + __field(unsigned long long, delta) + __field(unsigned long, total_scan) + ), + + TP_fast_assign( + __entry->shr = shr; + __entry->shrink = shr->shrink; + __entry->nr_objects_to_shrink = nr_objects_to_shrink; + __entry->gfp_flags = sc->gfp_mask; + __entry->pgs_scanned = pgs_scanned; + __entry->lru_pgs = lru_pgs; + __entry->cache_items = cache_items; + __entry->delta = delta; + __entry->total_scan = total_scan; + ), + + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", + __entry->shrink, + __entry->shr, + __entry->nr_objects_to_shrink, + show_gfp_flags(__entry->gfp_flags), + __entry->pgs_scanned, + __entry->lru_pgs, + __entry->cache_items, + __entry->delta, + __entry->total_scan) +); + +TRACE_EVENT(mm_shrink_slab_end, + TP_PROTO(struct shrinker *shr, int shrinker_retval, + long unused_scan_cnt, long new_scan_cnt), + + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, unused_scan) + __field(long, new_scan) + __field(int, retval) + __field(long, total_scan) + ), + + TP_fast_assign( + __entry->shr = shr; + __entry->shrink = shr->shrink; + __entry->unused_scan = unused_scan_cnt; + __entry->new_scan = new_scan_cnt; + __entry->retval = shrinker_retval; + __entry->total_scan = new_scan_cnt - unused_scan_cnt; + ), + + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", + __entry->shrink, + __entry->shr, + __entry->unused_scan, + __entry->new_scan, + __entry->total_scan, + __entry->retval) +); + +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, + int isolate_mode), + + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), + + TP_STRUCT__entry( + __field(int, order) + __field(unsigned long, nr_requested) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_taken) + __field(unsigned long, nr_lumpy_taken) + __field(unsigned long, nr_lumpy_dirty) + __field(unsigned long, nr_lumpy_failed) + __field(int, isolate_mode) + ), + + TP_fast_assign( + __entry->order = order; + __entry->nr_requested = nr_requested; + __entry->nr_scanned = nr_scanned; + __entry->nr_taken = nr_taken; + __entry->nr_lumpy_taken = nr_lumpy_taken; + __entry->nr_lumpy_dirty = nr_lumpy_dirty; + __entry->nr_lumpy_failed = nr_lumpy_failed; + __entry->isolate_mode = isolate_mode; + ), + + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", + __entry->isolate_mode, + __entry->order, + __entry->nr_requested, + __entry->nr_scanned, + __entry->nr_taken, + __entry->nr_lumpy_taken, + __entry->nr_lumpy_dirty, + __entry->nr_lumpy_failed) +); + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, + int isolate_mode), + + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) + +); + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, + int isolate_mode), + + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) + +); + +TRACE_EVENT(mm_vmscan_writepage, + + TP_PROTO(struct page *page, + int reclaim_flags), + + TP_ARGS(page, reclaim_flags), + + TP_STRUCT__entry( + __field(struct page *, page) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + __entry->page = page; + __entry->reclaim_flags = reclaim_flags; + ), + + TP_printk("page=%p pfn=%lu flags=%s", + __entry->page, + page_to_pfn(__entry->page), + show_reclaim_flags(__entry->reclaim_flags)) +); + +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, + + TP_PROTO(int nid, int zid, + unsigned long nr_scanned, unsigned long nr_reclaimed, + int priority, int reclaim_flags), + + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), + + TP_STRUCT__entry( + __field(int, nid) + __field(int, zid) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_reclaimed) + __field(int, priority) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + __entry->nid = nid; + __entry->zid = zid; + __entry->nr_scanned = nr_scanned; + __entry->nr_reclaimed = nr_reclaimed; + __entry->priority = priority; + __entry->reclaim_flags = reclaim_flags; + ), + + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", + __entry->nid, __entry->zid, + __entry->nr_scanned, __entry->nr_reclaimed, + __entry->priority, + show_reclaim_flags(__entry->reclaim_flags)) +); + +TRACE_EVENT(replace_swap_token, + TP_PROTO(struct mm_struct *old_mm, + struct mm_struct *new_mm), + + TP_ARGS(old_mm, new_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, old_mm) + __field(unsigned int, old_prio) + __field(struct mm_struct*, new_mm) + __field(unsigned int, new_prio) + ), + + TP_fast_assign( + __entry->old_mm = old_mm; + __entry->old_prio = old_mm ? old_mm->token_priority : 0; + __entry->new_mm = new_mm; + __entry->new_prio = new_mm->token_priority; + ), + + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", + __entry->old_mm, __entry->old_prio, + __entry->new_mm, __entry->new_prio) +); + +DECLARE_EVENT_CLASS(put_swap_token_template, + TP_PROTO(struct mm_struct *swap_token_mm), + + TP_ARGS(swap_token_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, swap_token_mm) + ), + + TP_fast_assign( + __entry->swap_token_mm = swap_token_mm; + ), + + TP_printk("token_mm=%p", __entry->swap_token_mm) +); + +DEFINE_EVENT(put_swap_token_template, put_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm) +); + +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm), + TP_CONDITION(swap_token_mm != NULL) +); + +TRACE_EVENT_CONDITION(update_swap_token_priority, + TP_PROTO(struct mm_struct *mm, + unsigned int old_prio, + struct mm_struct *swap_token_mm), + + TP_ARGS(mm, old_prio, swap_token_mm), + + TP_CONDITION(mm->token_priority != old_prio), + + TP_STRUCT__entry( + __field(struct mm_struct*, mm) + __field(unsigned int, old_prio) + __field(unsigned int, new_prio) + __field(struct mm_struct*, swap_token_mm) + __field(unsigned int, swap_token_prio) + ), + + TP_fast_assign( + __entry->mm = mm; + __entry->old_prio = old_prio; + __entry->new_prio = mm->token_priority; + __entry->swap_token_mm = swap_token_mm; + __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0; + ), + + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", + __entry->mm, __entry->old_prio, __entry->new_prio, + __entry->swap_token_mm, __entry->swap_token_prio) +); + +#endif /* _TRACE_VMSCAN_H */ + +/* This part must be outside protection */ +#include diff --git a/probes/Makefile b/probes/Makefile index 6efd6ad..c39a84a 100644 --- a/probes/Makefile +++ b/probes/Makefile @@ -12,6 +12,9 @@ obj-m += lttng-probe-lttng.o obj-m += lttng-probe-sched.o obj-m += lttng-probe-irq.o obj-m += lttng-probe-timer.o +obj-m += lttng-probe-kmem.o +obj-m += lttng-probe-module.o +obj-m += lttng-probe-power.o obj-m += lttng-probe-statedump.o @@ -33,6 +36,75 @@ obj-m += $(shell \ endif endif +ifneq ($(CONFIG_NET),) +obj-m += lttng-probe-net.o +obj-m += lttng-probe-napi.o +obj-m += lttng-probe-skb.o +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-sock.o" ; fi;) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-udp.o" ; fi;) +endif + +ifneq ($(CONFIG_SND_SOC),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ + echo "lttng-probe-asoc.o" ; fi;) +endif + +ifneq ($(CONFIG_EXT3_FS),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-ext3.o" ; fi;) +endif + +ifneq ($(CONFIG_GPIOLIB),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 ] ; then \ + echo "lttng-probe-gpio.o" ; fi;) +endif + +ifneq ($(CONFIG_JBD2),) +obj-m += lttng-probe-jbd2.o +endif + +ifneq ($(CONFIG_JBD),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-jbd.o" ; fi;) +endif + +ifneq ($(CONFIG_REGULATOR),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ + echo "lttng-probe-regulator.o" ; fi;) +endif + +ifneq ($(CONFIG_SCSI),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 ] ; then \ + echo "lttng-probe-scsi.o" ; fi;) +endif + +vmscan = $(shell \ + if [ $(VERSION) -ge 3 ] ; then \ + echo "lttng-probe-vmscan.o" ; fi;) +ifneq ($(CONFIG_SWAP),) + obj-m += $(vmscan) +else +ifneq ($(CONFIG_CGROUP_MEM_RES_CTLR),) + obj-m += $(vmscan) +endif +endif + +ifneq ($(CONFIG_LOCKDEP),) +obj-m += lttng-probe-lock.o +endif + ifneq ($(CONFIG_KPROBES),) obj-m += lttng-kprobes.o endif diff --git a/probes/lttng-probe-asoc.c b/probes/lttng-probe-asoc.c new file mode 100644 index 0000000..427639f --- /dev/null +++ b/probes/lttng-probe-asoc.c @@ -0,0 +1,45 @@ +/* + * probes/lttng-probe-block.c + * + * LTTng asoc probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/asoc.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng asoc probes"); diff --git a/probes/lttng-probe-ext3.c b/probes/lttng-probe-ext3.c new file mode 100644 index 0000000..0df2b67 --- /dev/null +++ b/probes/lttng-probe-ext3.c @@ -0,0 +1,56 @@ +/* + * probes/lttng-probe-ext3.c + * + * LTTng ext3 probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +/* + * Since 3.4 the is no linux/ext3_fs_i.h anymore. Instead we have to use + * ext3.h from fs/ext3/ext3.h (which also includes trace/events/ext3.h) + */ +#include "../instrumentation/events/mainline/fs_ext3.h" +#else +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include +#endif + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/ext3.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng ext3 probes"); diff --git a/probes/lttng-probe-gpio.c b/probes/lttng-probe-gpio.c new file mode 100644 index 0000000..51692a7 --- /dev/null +++ b/probes/lttng-probe-gpio.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-gpio.c + * + * LTTng gpio probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/gpio.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng gpio probes"); diff --git a/probes/lttng-probe-jbd.c b/probes/lttng-probe-jbd.c new file mode 100644 index 0000000..46911cc --- /dev/null +++ b/probes/lttng-probe-jbd.c @@ -0,0 +1,44 @@ +/* + * probes/lttng-probe-jbd.c + * + * LTTng jbd probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/jbd.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng jbd probes"); diff --git a/probes/lttng-probe-jbd2.c b/probes/lttng-probe-jbd2.c new file mode 100644 index 0000000..eea0a66 --- /dev/null +++ b/probes/lttng-probe-jbd2.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-jbd2.c + * + * LTTng jbd2 probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/jbd2.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng jbd2 probes"); diff --git a/probes/lttng-probe-kmem.c b/probes/lttng-probe-kmem.c new file mode 100644 index 0000000..af67759 --- /dev/null +++ b/probes/lttng-probe-kmem.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-kmem.c + * + * LTTng kmem probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/kmem.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng kmem probes"); diff --git a/probes/lttng-probe-lock.c b/probes/lttng-probe-lock.c new file mode 100644 index 0000000..16ac0e7 --- /dev/null +++ b/probes/lttng-probe-lock.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-lock.c + * + * LTTng lock probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/lock.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng lock probes"); diff --git a/probes/lttng-probe-module.c b/probes/lttng-probe-module.c new file mode 100644 index 0000000..1a3c255 --- /dev/null +++ b/probes/lttng-probe-module.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-module.c + * + * LTTng module probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/module.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng module probes"); diff --git a/probes/lttng-probe-napi.c b/probes/lttng-probe-napi.c new file mode 100644 index 0000000..cae8504 --- /dev/null +++ b/probes/lttng-probe-napi.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-napi.c + * + * LTTng napi probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/napi.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng napi probes"); diff --git a/probes/lttng-probe-net.c b/probes/lttng-probe-net.c new file mode 100644 index 0000000..54212be --- /dev/null +++ b/probes/lttng-probe-net.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-net.c + * + * LTTng net probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/net.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng net probes"); diff --git a/probes/lttng-probe-power.c b/probes/lttng-probe-power.c new file mode 100644 index 0000000..5dcb93f --- /dev/null +++ b/probes/lttng-probe-power.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-power.c + * + * LTTng power probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/power.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng power probes"); diff --git a/probes/lttng-probe-regulator.c b/probes/lttng-probe-regulator.c new file mode 100644 index 0000000..7c8b7f9 --- /dev/null +++ b/probes/lttng-probe-regulator.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-regulator.c + * + * LTTng regulator probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/regulator.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng regulator probes"); diff --git a/probes/lttng-probe-scsi.c b/probes/lttng-probe-scsi.c new file mode 100644 index 0000000..51702c3 --- /dev/null +++ b/probes/lttng-probe-scsi.c @@ -0,0 +1,44 @@ +/* + * probes/lttng-probe-scsi.c + * + * LTTng scsi probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/scsi.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng scsi probes"); diff --git a/probes/lttng-probe-skb.c b/probes/lttng-probe-skb.c new file mode 100644 index 0000000..52edf88 --- /dev/null +++ b/probes/lttng-probe-skb.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-skb.c + * + * LTTng skb probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/skb.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng skb probes"); diff --git a/probes/lttng-probe-sock.c b/probes/lttng-probe-sock.c new file mode 100644 index 0000000..b3e699a --- /dev/null +++ b/probes/lttng-probe-sock.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-sock.c + * + * LTTng sock probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/sock.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng sock probes"); diff --git a/probes/lttng-probe-udp.c b/probes/lttng-probe-udp.c new file mode 100644 index 0000000..51ec3cb --- /dev/null +++ b/probes/lttng-probe-udp.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-udp.c + * + * LTTng udp probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/udp.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng udp probes"); diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c new file mode 100644 index 0000000..2abd0e4 --- /dev/null +++ b/probes/lttng-probe-vmscan.c @@ -0,0 +1,48 @@ +/* + * probes/lttng-probe-vmscan.c + * + * LTTng vmscan probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) +typedef int isolate_mode_t; +#endif + +#include "../instrumentation/events/lttng-module/vmscan.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng vmscan probes"); -- 1.7.10.4 -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From mathieu.desnoyers at efficios.com Mon Nov 12 09:29:28 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 12 Nov 2012 09:29:28 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Additional kernel probes In-Reply-To: <50A0FB68.5060100@mentor.com> References: <50A0FB68.5060100@mentor.com> Message-ID: <20121112142928.GB23655@Krystal> * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > Hi Mathieu, Hi Paul, Great ! A couple of early comments below, > > we created a set of additional kernel probes for LTTng 2.0. > > The patch below adds asoc, ext3, gpio, jbd, jbd2, kmem, lock, module, > napi, net, power, regulator, scsi, skb, sock, udp, vmscan probes to > LTTng 2.0. > > The probes are verified to compile against all kernel versions from > 3.0 to 3.6 (3.7-rc5 also works). LTTng-modules states that 2.6.38 and 2.6.39 are supported too. Could you test those against these two kernel versions too ? More below, > > From 0f8a89285458f19c627c018d37891fafa9819fca Mon Sep 17 00:00:00 2001 > From: Paul Woegerer > Date: Mon, 12 Nov 2012 14:07:12 +0100 > Subject: [PATCH] Add kernel probes for asoc, ext3, gpio, jbd, jbd2, kmem, > lock, module, napi, net, power, regulator, scsi, skb, sock, > udp, vmscan. > > --- > instrumentation/events/lttng-module/asoc.h | 340 ++++++ > instrumentation/events/lttng-module/ext3.h | 870 +++++++++++++++ > instrumentation/events/lttng-module/gpio.h | 56 + > instrumentation/events/lttng-module/jbd.h | 243 +++++ > instrumentation/events/lttng-module/jbd2.h | 238 ++++ > instrumentation/events/lttng-module/kmem.h | 304 ++++++ > instrumentation/events/lttng-module/lock.h | 86 ++ > instrumentation/events/lttng-module/module.h | 134 +++ > instrumentation/events/lttng-module/napi.h | 38 + > instrumentation/events/lttng-module/net.h | 84 ++ > instrumentation/events/lttng-module/power.h | 240 ++++ > instrumentation/events/lttng-module/regulator.h | 141 +++ > instrumentation/events/lttng-module/scsi.h | 369 +++++++ > instrumentation/events/lttng-module/skb.h | 75 ++ > instrumentation/events/lttng-module/sock.h | 68 ++ > instrumentation/events/lttng-module/udp.h | 32 + > instrumentation/events/lttng-module/vmscan.h | 499 +++++++++ > instrumentation/events/mainline/asoc.h | 330 ++++++ > instrumentation/events/mainline/ext3.h | 864 +++++++++++++++ > instrumentation/events/mainline/fs_ext3.h | 1323 +++++++++++++++++++++++ > instrumentation/events/mainline/gpio.h | 56 + > instrumentation/events/mainline/jbd.h | 203 ++++ > instrumentation/events/mainline/jbd2.h | 235 ++++ > instrumentation/events/mainline/kmem.h | 308 ++++++ > instrumentation/events/mainline/lock.h | 86 ++ > instrumentation/events/mainline/module.h | 131 +++ > instrumentation/events/mainline/napi.h | 38 + > instrumentation/events/mainline/net.h | 84 ++ > instrumentation/events/mainline/power.h | 240 ++++ > instrumentation/events/mainline/regulator.h | 141 +++ > instrumentation/events/mainline/scsi.h | 365 +++++++ > instrumentation/events/mainline/skb.h | 75 ++ > instrumentation/events/mainline/sock.h | 68 ++ > instrumentation/events/mainline/udp.h | 32 + > instrumentation/events/mainline/vmscan.h | 477 ++++++++ > probes/Makefile | 72 ++ > probes/lttng-probe-asoc.c | 45 + > probes/lttng-probe-ext3.c | 56 + > probes/lttng-probe-gpio.c | 43 + > probes/lttng-probe-jbd.c | 44 + > probes/lttng-probe-jbd2.c | 43 + > probes/lttng-probe-kmem.c | 43 + > probes/lttng-probe-lock.c | 43 + > probes/lttng-probe-module.c | 43 + > probes/lttng-probe-napi.c | 43 + > probes/lttng-probe-net.c | 43 + > probes/lttng-probe-power.c | 43 + > probes/lttng-probe-regulator.c | 43 + > probes/lttng-probe-scsi.c | 44 + > probes/lttng-probe-skb.c | 43 + > probes/lttng-probe-sock.c | 43 + > probes/lttng-probe-udp.c | 43 + > probes/lttng-probe-vmscan.c | 48 + > 53 files changed, 9698 insertions(+) > create mode 100644 instrumentation/events/lttng-module/asoc.h > create mode 100644 instrumentation/events/lttng-module/ext3.h > create mode 100644 instrumentation/events/lttng-module/gpio.h > create mode 100644 instrumentation/events/lttng-module/jbd.h > create mode 100644 instrumentation/events/lttng-module/jbd2.h > create mode 100644 instrumentation/events/lttng-module/kmem.h > create mode 100644 instrumentation/events/lttng-module/lock.h > create mode 100644 instrumentation/events/lttng-module/module.h > create mode 100644 instrumentation/events/lttng-module/napi.h > create mode 100644 instrumentation/events/lttng-module/net.h > create mode 100644 instrumentation/events/lttng-module/power.h > create mode 100644 instrumentation/events/lttng-module/regulator.h > create mode 100644 instrumentation/events/lttng-module/scsi.h > create mode 100644 instrumentation/events/lttng-module/skb.h > create mode 100644 instrumentation/events/lttng-module/sock.h > create mode 100644 instrumentation/events/lttng-module/udp.h > create mode 100644 instrumentation/events/lttng-module/vmscan.h > create mode 100644 instrumentation/events/mainline/asoc.h > create mode 100644 instrumentation/events/mainline/ext3.h > create mode 100644 instrumentation/events/mainline/fs_ext3.h > create mode 100644 instrumentation/events/mainline/gpio.h > create mode 100644 instrumentation/events/mainline/jbd.h > create mode 100644 instrumentation/events/mainline/jbd2.h > create mode 100644 instrumentation/events/mainline/kmem.h > create mode 100644 instrumentation/events/mainline/lock.h > create mode 100644 instrumentation/events/mainline/module.h > create mode 100644 instrumentation/events/mainline/napi.h > create mode 100644 instrumentation/events/mainline/net.h > create mode 100644 instrumentation/events/mainline/power.h > create mode 100644 instrumentation/events/mainline/regulator.h > create mode 100644 instrumentation/events/mainline/scsi.h > create mode 100644 instrumentation/events/mainline/skb.h > create mode 100644 instrumentation/events/mainline/sock.h > create mode 100644 instrumentation/events/mainline/udp.h > create mode 100644 instrumentation/events/mainline/vmscan.h > create mode 100644 probes/lttng-probe-asoc.c > create mode 100644 probes/lttng-probe-ext3.c > create mode 100644 probes/lttng-probe-gpio.c > create mode 100644 probes/lttng-probe-jbd.c > create mode 100644 probes/lttng-probe-jbd2.c > create mode 100644 probes/lttng-probe-kmem.c > create mode 100644 probes/lttng-probe-lock.c > create mode 100644 probes/lttng-probe-module.c > create mode 100644 probes/lttng-probe-napi.c > create mode 100644 probes/lttng-probe-net.c > create mode 100644 probes/lttng-probe-power.c > create mode 100644 probes/lttng-probe-regulator.c > create mode 100644 probes/lttng-probe-scsi.c > create mode 100644 probes/lttng-probe-skb.c > create mode 100644 probes/lttng-probe-sock.c > create mode 100644 probes/lttng-probe-udp.c > create mode 100644 probes/lttng-probe-vmscan.c > > diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h > new file mode 100644 > index 0000000..cb9e701 > --- /dev/null > +++ b/instrumentation/events/lttng-module/asoc.h > @@ -0,0 +1,340 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM asoc > + > +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_ASOC_H > + > +#include > +#include > +#include > + > +#ifndef _TRACE_ASOC_DEF > +#define _TRACE_ASOC_DEF > +struct snd_soc_jack; > +struct snd_soc_codec; > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) > +struct snd_soc_platform; > +#endif > +struct snd_soc_card; > +struct snd_soc_dapm_widget; > +#endif > + > +/* > + * Log register events > + */ > +DECLARE_EVENT_CLASS(snd_soc_reg, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, codec->name); > + tp_assign(id, codec->id); > + tp_assign(reg, reg); > + tp_assign(val, val); lttng-modules TP_fast_assign() section should not have semicolumn at the end of lines, e.g.: TP_fast_assign( tp_strcpy(name, codec->name) tp_assign(id, codec->id) tp_assign(reg, reg) tp_assign(val, val) ) Thanks, Mathieu > + ), > + > + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +) > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +) > + > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) > +DECLARE_EVENT_CLASS(snd_soc_preg, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val), > + > + TP_STRUCT__entry( > + __string( name, platform->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, platform->name); > + tp_assign(id, platform->id); > + tp_assign(reg, reg); > + tp_assign(val, val); > + ), > + > + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +) > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +) > +#endif > + > +DECLARE_EVENT_CLASS(snd_soc_card, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, card->name); > + tp_assign(val, val); > + ), > + > + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +) > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +) > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, card->name); > + ), > + > + TP_printk("card=%s", __get_str(name)) > +) > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +) > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +) > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val), > + > + TP_STRUCT__entry( > + __string( name, w->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, w->name); > + tp_assign(val, val); > + ), > + > + TP_printk("widget=%s val=%d", __get_str(name), > + (int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +) > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +) > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +) > + > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) > +TRACE_EVENT(snd_soc_dapm_walk_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, power_checks ) > + __field( int, path_checks ) > + __field( int, neighbour_checks ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, card->name); > + tp_assign(power_checks, card->dapm_stats.power_checks); > + tp_assign(path_checks, card->dapm_stats.path_checks); > + tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks); > + ), > + > + TP_printk("%s: checks %d power, %d path, %d neighbour", > + __get_str(name), (int)__entry->power_checks, > + (int)__entry->path_checks, (int)__entry->neighbour_checks) > +) > +#endif > + > +TRACE_EVENT(snd_soc_jack_irq, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + ), > + > + TP_printk("%s", __get_str(name)) > +) > + > +TRACE_EVENT(snd_soc_jack_report, > + > + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), > + > + TP_ARGS(jack, mask, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, mask ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, jack->jack->name); > + tp_assign(mask, mask); > + tp_assign(val, val); > + ), > + > + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, > + (int)__entry->mask) > +) > + > +TRACE_EVENT(snd_soc_jack_notify, > + > + TP_PROTO(struct snd_soc_jack *jack, int val), > + > + TP_ARGS(jack, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, jack->jack->name); > + tp_assign(val, val); > + ), > + > + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) > +) > + > +TRACE_EVENT(snd_soc_cache_sync, > + > + TP_PROTO(struct snd_soc_codec *codec, const char *type, > + const char *status), > + > + TP_ARGS(codec, type, status), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __string( status, status ) > + __string( type, type ) > + __field( int, id ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, codec->name); > + tp_strcpy(status, status); > + tp_strcpy(type, type); > + tp_assign(id, codec->id); > + ), > + > + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), > + (int)__entry->id, __get_str(type), __get_str(status)) > +) > + > +#endif /* _TRACE_ASOC_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h > new file mode 100644 > index 0000000..e02ecf4 > --- /dev/null > +++ b/instrumentation/events/lttng-module/ext3.h > @@ -0,0 +1,870 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM ext3 > + > +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_EXT3_H > + > +#include > + > +#ifndef _TRACE_EXT3_DEF > +#define _TRACE_EXT3_DEF > +static struct dentry *dentry; > +#endif > + > + > +TRACE_EVENT(ext3_free_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( uid_t, uid ) > + __field( gid_t, gid ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(mode, inode->i_mode); > + tp_assign(uid, inode->i_uid); > + tp_assign(gid, inode->i_gid); > + tp_assign(blocks, inode->i_blocks); > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->uid, __entry->gid, > + (unsigned long) __entry->blocks) > +) > + > +TRACE_EVENT(ext3_request_inode, > + TP_PROTO(struct inode *dir, int mode), > + > + TP_ARGS(dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, dir->i_sb->s_dev); > + tp_assign(dir, dir->i_ino); > + tp_assign(mode, mode); > + ), > + > + TP_printk("dev %d,%d dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->dir, __entry->mode) > +) > + > +TRACE_EVENT(ext3_allocate_inode, > + TP_PROTO(struct inode *inode, struct inode *dir, int mode), > + > + TP_ARGS(inode, dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(dir, dir->i_ino); > + tp_assign(mode, mode); > + ), > + > + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->dir, __entry->mode) > +) > + > +TRACE_EVENT(ext3_evict_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, nlink ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(nlink, inode->i_nlink); > + ), > + > + TP_printk("dev %d,%d ino %lu nlink %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->nlink) > +) > + > +TRACE_EVENT(ext3_drop_inode, > + TP_PROTO(struct inode *inode, int drop), > + > + TP_ARGS(inode, drop), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, drop ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(drop, drop); > + ), > + > + TP_printk("dev %d,%d ino %lu drop %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->drop) > +) > + > +TRACE_EVENT(ext3_mark_inode_dirty, > + TP_PROTO(struct inode *inode, unsigned long IP), > + > + TP_ARGS(inode, IP), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field(unsigned long, ip ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(ip, IP); > + ), > + > + TP_printk("dev %d,%d ino %lu caller %pF", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (void *)__entry->ip) > +) > + > +TRACE_EVENT(ext3_write_begin, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int flags), > + > + TP_ARGS(inode, pos, len, flags), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, flags ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(pos, pos); > + tp_assign(len, len); > + tp_assign(flags, flags); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->flags) > +) > + > +DECLARE_EVENT_CLASS(ext3__write_end, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, copied ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(pos, pos); > + tp_assign(len, len); > + tp_assign(copied, copied); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->copied) > +) > + > +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +) > + > +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +) > + > +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +) > + > +DECLARE_EVENT_CLASS(ext3__page_op, > + TP_PROTO(struct page *page), > + > + TP_ARGS(page), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( pgoff_t, index ) > + > + ), > + > + TP_fast_assign( > + tp_assign(index, page->index); > + tp_assign(ino, page->mapping->host->i_ino); > + tp_assign(dev, page->mapping->host->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->index) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_readpage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_releasepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +TRACE_EVENT(ext3_invalidatepage, > + TP_PROTO(struct page *page, unsigned long offset), > + > + TP_ARGS(page, offset), > + > + TP_STRUCT__entry( > + __field( pgoff_t, index ) > + __field( unsigned long, offset ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + > + ), > + > + TP_fast_assign( > + tp_assign(index, page->index); > + tp_assign(offset, offset); > + tp_assign(ino, page->mapping->host->i_ino); > + tp_assign(dev, page->mapping->host->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->index, __entry->offset) > +) > + > +TRACE_EVENT(ext3_discard_blocks, > + TP_PROTO(struct super_block *sb, unsigned long blk, > + unsigned long count), > + > + TP_ARGS(sb, blk, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, blk ) > + __field( unsigned long, count ) > + > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(blk, blk); > + tp_assign(count, count); > + ), > + > + TP_printk("dev %d,%d blk %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->blk, __entry->count) > +) > + > +TRACE_EVENT(ext3_request_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count), > + > + TP_ARGS(inode, goal, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(count, count); > + tp_assign(goal, goal); > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->goal) > +) > + > +TRACE_EVENT(ext3_allocate_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count, unsigned long block), > + > + TP_ARGS(inode, goal, count, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(block, block); > + tp_assign(count, count); > + tp_assign(goal, goal); > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->block, > + __entry->goal) > +) > + > +TRACE_EVENT(ext3_free_blocks, > + TP_PROTO(struct inode *inode, unsigned long block, > + unsigned long count), > + > + TP_ARGS(inode, block, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(mode, inode->i_mode); > + tp_assign(block, block); > + tp_assign(count, count); > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->block, __entry->count) > +) > + > +TRACE_EVENT(ext3_sync_file_enter, > + TP_PROTO(struct file *file, int datasync), > + > + TP_ARGS(file, datasync), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, parent ) > + __field( int, datasync ) > + ), > + > + TP_fast_assign( > + dentry = file->f_path.dentry; > + > + tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + tp_assign(ino, dentry->d_inode->i_ino); > + tp_assign(datasync, datasync); > + tp_assign(parent, dentry->d_parent->d_inode->i_ino); > + ), > + > + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->parent, __entry->datasync) > +) > + > +TRACE_EVENT(ext3_sync_file_exit, > + TP_PROTO(struct inode *inode, int ret), > + > + TP_ARGS(inode, ret), > + > + TP_STRUCT__entry( > + __field( int, ret ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(ret, ret); > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +) > + > +TRACE_EVENT(ext3_sync_fs, > + TP_PROTO(struct super_block *sb, int wait), > + > + TP_ARGS(sb, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(wait, wait); > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +) > + > +TRACE_EVENT(ext3_rsv_window_add, > + TP_PROTO(struct super_block *sb, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(start, rsv_node->rsv_window._rsv_start); > + tp_assign(end, rsv_node->rsv_window._rsv_end); > + ), > + > + TP_printk("dev %d,%d start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->start, __entry->end) > +) > + > +TRACE_EVENT(ext3_discard_reservation, > + TP_PROTO(struct inode *inode, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(inode, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(start, rsv_node->rsv_window._rsv_start); > + tp_assign(end, rsv_node->rsv_window._rsv_end); > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long)__entry->ino, __entry->start, > + __entry->end) > +) > + > +TRACE_EVENT(ext3_alloc_new_reservation, > + TP_PROTO(struct super_block *sb, unsigned long goal), > + > + TP_ARGS(sb, goal), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(goal, goal); > + ), > + > + TP_printk("dev %d,%d goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->goal) > +) > + > +TRACE_EVENT(ext3_reserved, > + TP_PROTO(struct super_block *sb, unsigned long block, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, block, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, block ) > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(block, block); > + tp_assign(start, rsv_node->rsv_window._rsv_start); > + tp_assign(end, rsv_node->rsv_window._rsv_end); > + tp_assign(dev, sb->s_dev); > + ), > + > + TP_printk("dev %d,%d block %lu, start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->block, __entry->start, __entry->end) > +) > + > +TRACE_EVENT(ext3_forget, > + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), > + > + TP_ARGS(inode, is_metadata, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( int, is_metadata ) > + __field( unsigned long, block ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(mode, inode->i_mode); > + tp_assign(is_metadata, is_metadata); > + tp_assign(block, block); > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->is_metadata, __entry->block) > +) > + > +TRACE_EVENT(ext3_read_block_bitmap, > + TP_PROTO(struct super_block *sb, unsigned int group), > + > + TP_ARGS(sb, group), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( __u32, group ) > + > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(group, group); > + ), > + > + TP_printk("dev %d,%d group %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->group) > +) > + > +TRACE_EVENT(ext3_direct_IO_enter, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), > + > + TP_ARGS(inode, offset, len, rw), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(pos, offset); > + tp_assign(len, len); > + tp_assign(rw, rw); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw) > +) > + > +TRACE_EVENT(ext3_direct_IO_exit, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, > + int rw, int ret), > + > + TP_ARGS(inode, offset, len, rw, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(pos, offset); > + tp_assign(len, len); > + tp_assign(rw, rw); > + tp_assign(ret, ret); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw, __entry->ret) > +) > + > +TRACE_EVENT(ext3_unlink_enter, > + TP_PROTO(struct inode *parent, struct dentry *dentry), > + > + TP_ARGS(parent, dentry), > + > + TP_STRUCT__entry( > + __field( ino_t, parent ) > + __field( ino_t, ino ) > + __field( loff_t, size ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(parent, parent->i_ino); > + tp_assign(ino, dentry->d_inode->i_ino); > + tp_assign(size, dentry->d_inode->i_size); > + tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu size %lld parent %ld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long)__entry->size, > + (unsigned long) __entry->parent) > +) > + > +TRACE_EVENT(ext3_unlink_exit, > + TP_PROTO(struct dentry *dentry, int ret), > + > + TP_ARGS(dentry, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, dentry->d_inode->i_ino); > + tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + tp_assign(ret, ret); > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +) > + > +DECLARE_EVENT_CLASS(ext3__truncate, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(blocks, inode->i_blocks); > + ), > + > + TP_printk("dev %d,%d ino %lu blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) > +) > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +) > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +) > + > +TRACE_EVENT(ext3_get_blocks_enter, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long len, int create), > + > + TP_ARGS(inode, lblk, len, create), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, len ) > + __field( int, create ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(lblk, lblk); > + tp_assign(len, len); > + tp_assign(create, create); > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->len, __entry->create) > +) > + > +TRACE_EVENT(ext3_get_blocks_exit, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long pblk, unsigned long len, int ret), > + > + TP_ARGS(inode, lblk, pblk, len, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, pblk ) > + __field( unsigned long, len ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(lblk, lblk); > + tp_assign(pblk, pblk); > + tp_assign(len, len); > + tp_assign(ret, ret); > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->pblk, > + __entry->len, __entry->ret) > +) > + > +TRACE_EVENT(ext3_load_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +) > + > +#endif /* _TRACE_EXT3_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/gpio.h b/instrumentation/events/lttng-module/gpio.h > new file mode 100644 > index 0000000..e6002c4 > --- /dev/null > +++ b/instrumentation/events/lttng-module/gpio.h > @@ -0,0 +1,56 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM gpio > + > +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_GPIO_H > + > +#include > + > +TRACE_EVENT(gpio_direction, > + > + TP_PROTO(unsigned gpio, int in, int err), > + > + TP_ARGS(gpio, in, err), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, in) > + __field(int, err) > + ), > + > + TP_fast_assign( > + tp_assign(gpio, gpio); > + tp_assign(in, in); > + tp_assign(err, err); > + ), > + > + TP_printk("%u %3s (%d)", __entry->gpio, > + __entry->in ? "in" : "out", __entry->err) > +) > + > +TRACE_EVENT(gpio_value, > + > + TP_PROTO(unsigned gpio, int get, int value), > + > + TP_ARGS(gpio, get, value), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, get) > + __field(int, value) > + ), > + > + TP_fast_assign( > + tp_assign(gpio, gpio); > + tp_assign(get, get); > + tp_assign(value, value); > + ), > + > + TP_printk("%u %3s %d", __entry->gpio, > + __entry->get ? "get" : "set", __entry->value) > +) > + > +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h > new file mode 100644 > index 0000000..97ba1e5 > --- /dev/null > +++ b/instrumentation/events/lttng-module/jbd.h > @@ -0,0 +1,243 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd > + > +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD_H > + > +#include > +#include > + > +TRACE_EVENT(jbd_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(result, result); > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->result) > +) > + > +DECLARE_EVENT_CLASS(jbd_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +#else > + TP_printk("dev %d,%d transaction %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction) > +#endif > +) > + > +DEFINE_EVENT(jbd_commit, jbd_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd_commit, jbd_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd_commit, jbd_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +TRACE_EVENT(jbd_drop_transaction, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +#else > + TP_printk("dev %d,%d transaction %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction) > +#endif > +) > + > +TRACE_EVENT(jbd_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(head, journal->j_tail_sequence); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +#else > + TP_printk("dev %d,%d transaction %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->head) > +#endif > +) > + > +TRACE_EVENT(jbd_do_submit_data, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +#else > + TP_printk("dev %d,%d transaction %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction) > +#endif > +) > + > +TRACE_EVENT(jbd_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(tail_sequence, journal->j_tail_sequence); > + tp_assign(first_tid, first_tid); > + tp_assign(block_nr, block_nr); > + tp_assign(freed, freed); > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +) > + > +TRACE_EVENT(jbd_update_superblock_end, > + TP_PROTO(journal_t *journal, int wait), > + > + TP_ARGS(journal, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(wait, wait); > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +) > + > +#endif /* _TRACE_JBD_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h > new file mode 100644 > index 0000000..2e80832 > --- /dev/null > +++ b/instrumentation/events/lttng-module/jbd2.h > @@ -0,0 +1,238 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd2 > + > +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD2_H > + > +#include > +#include > + > +#ifndef _TRACE_JBD2_DEF > +#define _TRACE_JBD2_DEF > +struct transaction_chp_stats_s; > +struct transaction_run_stats_s; > +#endif > + > +TRACE_EVENT(jbd2_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(result, result); > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) > +) > + > +DECLARE_EVENT_CLASS(jbd2_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +TRACE_EVENT(jbd2_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(head, journal->j_tail_sequence); > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +) > + > +TRACE_EVENT(jbd2_submit_inode_data, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +) > + > +TRACE_EVENT(jbd2_run_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_run_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, wait ) > + __field( unsigned long, running ) > + __field( unsigned long, locked ) > + __field( unsigned long, flushing ) > + __field( unsigned long, logging ) > + __field( __u32, handle_count ) > + __field( __u32, blocks ) > + __field( __u32, blocks_logged ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, dev); > + tp_assign(tid, tid); > + tp_assign(wait, stats->rs_wait); > + tp_assign(running, stats->rs_running); > + tp_assign(locked, stats->rs_locked); > + tp_assign(flushing, stats->rs_flushing); > + tp_assign(logging, stats->rs_logging); > + tp_assign(handle_count, stats->rs_handle_count); > + tp_assign(blocks, stats->rs_blocks); > + tp_assign(blocks_logged, stats->rs_blocks_logged); > + ), > + > + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " > + "logging %u handle_count %u blocks %u blocks_logged %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->wait), > + jiffies_to_msecs(__entry->running), > + jiffies_to_msecs(__entry->locked), > + jiffies_to_msecs(__entry->flushing), > + jiffies_to_msecs(__entry->logging), > + __entry->handle_count, __entry->blocks, > + __entry->blocks_logged) > +) > + > +TRACE_EVENT(jbd2_checkpoint_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_chp_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, chp_time ) > + __field( __u32, forced_to_close ) > + __field( __u32, written ) > + __field( __u32, dropped ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, dev); > + tp_assign(tid, tid); > + tp_assign(chp_time, stats->cs_chp_time); > + tp_assign(forced_to_close, stats->cs_forced_to_close); > + tp_assign(written, stats->cs_written); > + tp_assign(dropped, stats->cs_dropped); > + ), > + > + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " > + "written %u dropped %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->chp_time), > + __entry->forced_to_close, __entry->written, __entry->dropped) > +) > + > +TRACE_EVENT(jbd2_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(tail_sequence, journal->j_tail_sequence); > + tp_assign(first_tid, first_tid); > + tp_assign(block_nr, block_nr); > + tp_assign(freed, freed); > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +) > + > +#endif /* _TRACE_JBD2_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h > new file mode 100644 > index 0000000..04f668b > --- /dev/null > +++ b/instrumentation/events/lttng-module/kmem.h > @@ -0,0 +1,304 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM kmem > + > +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_KMEM_H > + > +DECLARE_EVENT_CLASS(kmem_alloc, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + tp_assign(call_site, call_site); > + tp_assign(ptr, ptr); > + tp_assign(bytes_req, bytes_req); > + tp_assign(bytes_alloc, bytes_alloc); > + tp_assign(gfp_flags, gfp_flags); > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags)) > +) > + > +DEFINE_EVENT(kmem_alloc, kmalloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +) > + > +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +) > + > +DECLARE_EVENT_CLASS(kmem_alloc_node, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags, > + int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + __field( int, node ) > + ), > + > + TP_fast_assign( > + tp_assign(call_site, call_site); > + tp_assign(ptr, ptr); > + tp_assign(bytes_req, bytes_req); > + tp_assign(bytes_alloc, bytes_alloc); > + tp_assign(gfp_flags, gfp_flags); > + tp_assign(node, node); > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags), > + __entry->node) > +) > + > +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +) > + > +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +) > + > +DECLARE_EVENT_CLASS(kmem_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + ), > + > + TP_fast_assign( > + tp_assign(call_site, call_site); > + tp_assign(ptr, ptr); > + ), > + > + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > +) > + > +DEFINE_EVENT(kmem_free, kfree, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +) > + > +DEFINE_EVENT(kmem_free, kmem_cache_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +) > + > +TRACE_EVENT(mm_page_free_direct, > + > + TP_PROTO(struct page *page, unsigned int order), > + > + TP_ARGS(page, order), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(order, order); > + ), > + > + TP_printk("page=%p pfn=%lu order=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order) > +) > + > +TRACE_EVENT(mm_pagevec_free, > + > + TP_PROTO(struct page *page, int cold), > + > + TP_ARGS(page, cold), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, cold ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(cold, cold); > + ), > + > + TP_printk("page=%p pfn=%lu order=0 cold=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->cold) > +) > + > +TRACE_EVENT(mm_page_alloc, > + > + TP_PROTO(struct page *page, unsigned int order, > + gfp_t gfp_flags, int migratetype), > + > + TP_ARGS(page, order, gfp_flags, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( gfp_t, gfp_flags ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(order, order); > + tp_assign(gfp_flags, gfp_flags); > + tp_assign(migratetype, migratetype); > + ), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + show_gfp_flags(__entry->gfp_flags)) > +) > + > +DECLARE_EVENT_CLASS(mm_page, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(order, order); > + tp_assign(migratetype, migratetype); > + ), > + > + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + __entry->order == 0) > +) > + > +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype) > +) > + > +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", > + __entry->page, page_to_pfn(__entry->page), > + __entry->order, __entry->migratetype) > +) > + > +TRACE_EVENT(mm_page_alloc_extfrag, > + > + TP_PROTO(struct page *page, > + int alloc_order, int fallback_order, > + int alloc_migratetype, int fallback_migratetype), > + > + TP_ARGS(page, > + alloc_order, fallback_order, > + alloc_migratetype, fallback_migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, alloc_order ) > + __field( int, fallback_order ) > + __field( int, alloc_migratetype ) > + __field( int, fallback_migratetype ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(alloc_order, alloc_order); > + tp_assign(fallback_order, fallback_order); > + tp_assign(alloc_migratetype, alloc_migratetype); > + tp_assign(fallback_migratetype, fallback_migratetype); > + ), > + > + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->alloc_order, > + __entry->fallback_order, > + pageblock_order, > + __entry->alloc_migratetype, > + __entry->fallback_migratetype, > + __entry->fallback_order < pageblock_order, > + __entry->alloc_migratetype == __entry->fallback_migratetype) > +) > + > +#endif /* _TRACE_KMEM_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/lock.h b/instrumentation/events/lttng-module/lock.h > new file mode 100644 > index 0000000..75101f6 > --- /dev/null > +++ b/instrumentation/events/lttng-module/lock.h > @@ -0,0 +1,86 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM lock > + > +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_LOCK_H > + > +#include > +#include > + > +#ifdef CONFIG_LOCKDEP > + > +TRACE_EVENT(lock_acquire, > + > + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, > + int trylock, int read, int check, > + struct lockdep_map *next_lock, unsigned long ip), > + > + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), > + > + TP_STRUCT__entry( > + __field(unsigned int, flags) > + __string(name, lock->name) > + __field(void *, lockdep_addr) > + ), > + > + TP_fast_assign( > + tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)); > + tp_strcpy(name, lock->name); > + tp_assign(lockdep_addr, lock); > + ), > + > + TP_printk("%p %s%s%s", __entry->lockdep_addr, > + (__entry->flags & 1) ? "try " : "", > + (__entry->flags & 2) ? "read " : "", > + __get_str(name)) > +) > + > +DECLARE_EVENT_CLASS(lock, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip), > + > + TP_STRUCT__entry( > + __string( name, lock->name ) > + __field( void *, lockdep_addr ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, lock->name); > + tp_assign(lockdep_addr, lock); > + ), > + > + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) > +) > + > +DEFINE_EVENT(lock, lock_release, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +) > + > +#ifdef CONFIG_LOCK_STAT > + > +DEFINE_EVENT(lock, lock_contended, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +) > + > +DEFINE_EVENT(lock, lock_acquired, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +) > + > +#endif > +#endif > + > +#endif /* _TRACE_LOCK_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/module.h b/instrumentation/events/lttng-module/module.h > new file mode 100644 > index 0000000..2e83431 > --- /dev/null > +++ b/instrumentation/events/lttng-module/module.h > @@ -0,0 +1,134 @@ > +/* > + * Because linux/module.h has tracepoints in the header, and ftrace.h > + * eventually includes this file, define_trace.h includes linux/module.h > + * But we do not want the module.h to override the TRACE_SYSTEM macro > + * variable that define_trace.h is processing, so we only set it > + * when module events are being processed, which would happen when > + * CREATE_TRACE_POINTS is defined. > + */ > +#ifdef CREATE_TRACE_POINTS > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM module > +#endif > + > +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_MODULE_H > + > +#include > + > +#ifdef CONFIG_MODULES > + > +#ifndef _TRACE_MODULE_DEF > +#define _TRACE_MODULE_DEF > +struct module; > + > +#define show_module_flags(flags) __print_flags(flags, "", \ > + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ > + { (1UL << TAINT_FORCED_MODULE), "F" }, \ > + { (1UL << TAINT_CRAP), "C" }) > +#endif > + > +TRACE_EVENT(module_load, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __field( unsigned int, taints ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + tp_assign(taints, mod->taints); > + tp_strcpy(name, mod->name); > + ), > + > + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) > +) > + > +TRACE_EVENT(module_free, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, mod->name); > + ), > + > + TP_printk("%s", __get_str(name)) > +) > + > +#ifdef CONFIG_MODULE_UNLOAD > +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ > + > +DECLARE_EVENT_CLASS(module_refcnt, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( int, refcnt ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + tp_assign(ip, ip); > + tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)); > + tp_strcpy(name, mod->name); > + ), > + > + TP_printk("%s call_site=%pf refcnt=%d", > + __get_str(name), (void *)__entry->ip, __entry->refcnt) > +) > + > +DEFINE_EVENT(module_refcnt, module_get, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +) > + > +DEFINE_EVENT(module_refcnt, module_put, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +) > +#endif /* CONFIG_MODULE_UNLOAD */ > + > +TRACE_EVENT(module_request, > + > + TP_PROTO(char *name, bool wait, unsigned long ip), > + > + TP_ARGS(name, wait, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( bool, wait ) > + __string( name, name ) > + ), > + > + TP_fast_assign( > + tp_assign(ip, ip); > + tp_assign(wait, wait); > + tp_strcpy(name, name); > + ), > + > + TP_printk("%s wait=%d call_site=%pf", > + __get_str(name), (int)__entry->wait, (void *)__entry->ip) > +) > + > +#endif /* CONFIG_MODULES */ > + > +#endif /* _TRACE_MODULE_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/napi.h b/instrumentation/events/lttng-module/napi.h > new file mode 100644 > index 0000000..58b8336 > --- /dev/null > +++ b/instrumentation/events/lttng-module/napi.h > @@ -0,0 +1,38 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM napi > + > +#if !defined(_TRACE_NAPI_H_) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NAPI_H_ > + > +#include > +#include > +#include > + > +#define NO_DEV "(no_device)" > + > +TRACE_EVENT(napi_poll, > + > + TP_PROTO(struct napi_struct *napi), > + > + TP_ARGS(napi), > + > + TP_STRUCT__entry( > + __field( struct napi_struct *, napi) > + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) > + ), > + > + TP_fast_assign( > + tp_assign(napi, napi); > + tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV); > + ), > + > + TP_printk("napi poll on napi struct %p for device %s", > + __entry->napi, __get_str(dev_name)) > +) > + > +#undef NO_DEV > + > +#endif /* _TRACE_NAPI_H_ */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h > new file mode 100644 > index 0000000..c25b0d9 > --- /dev/null > +++ b/instrumentation/events/lttng-module/net.h > @@ -0,0 +1,84 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM net > + > +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NET_H > + > +#include > +#include > +#include > +#include > + > +TRACE_EVENT(net_dev_xmit, > + > + TP_PROTO(struct sk_buff *skb, > + int rc, > + struct net_device *dev, > + unsigned int skb_len), > + > + TP_ARGS(skb, rc, dev, skb_len), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __field( int, rc ) > + __string( name, dev->name ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, skb_len); > + tp_assign(rc, rc); > + tp_strcpy(name, dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", > + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) > +) > + > +DECLARE_EVENT_CLASS(net_dev_template, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __string( name, skb->dev->name ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, skb->len); > + tp_strcpy(name, skb->dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u", > + __get_str(name), __entry->skbaddr, __entry->len) > +) > + > +DEFINE_EVENT(net_dev_template, net_dev_queue, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +) > + > +DEFINE_EVENT(net_dev_template, netif_receive_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +) > + > +DEFINE_EVENT(net_dev_template, netif_rx, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +) > +#endif /* _TRACE_NET_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h > new file mode 100644 > index 0000000..05aced7 > --- /dev/null > +++ b/instrumentation/events/lttng-module/power.h > @@ -0,0 +1,240 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM power > + > +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_POWER_H > + > +#include > +#include > + > +DECLARE_EVENT_CLASS(cpu, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + __field( u32, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, > + (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(cpu, cpu_idle, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id) > +) > + > +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING > + > +#define PWR_EVENT_EXIT -1 > +#endif > + > +DEFINE_EVENT(cpu, cpu_frequency, > + > + TP_PROTO(unsigned int frequency, unsigned int cpu_id), > + > + TP_ARGS(frequency, cpu_id) > +) > + > +TRACE_EVENT(machine_suspend, > + > + TP_PROTO(unsigned int state), > + > + TP_ARGS(state), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + ), > + > + TP_fast_assign( > + tp_assign(state, state); > + ), > + > + TP_printk("state=%lu", (unsigned long)__entry->state) > +) > + > +/* This code will be removed after deprecation time exceeded (2.6.41) */ > +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED > + > +/* > + * The power events are used for cpuidle & suspend (power_start, power_end) > + * and for cpufreq (power_frequency) > + */ > +DECLARE_EVENT_CLASS(power, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, type ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_assign(type, type); > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(power, power_start, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +) > + > +DEFINE_EVENT(power, power_frequency, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +) > + > +TRACE_EVENT(power_end, > + > + TP_PROTO(unsigned int cpu_id), > + > + TP_ARGS(cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) > + > +) > + > +/* Deprecated dummy functions must be protected against multi-declartion */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > + > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > + > +/* These dummy declaration have to be ripped out when the deprecated > + events get removed */ > +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; > +static inline void trace_power_end(u64 cpuid) {}; > +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +/* > + * The clock events are used for clock enable/disable and for > + * clock rate change > + */ > +DECLARE_EVENT_CLASS(clock, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(clock, clock_enable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > + > +DEFINE_EVENT(clock, clock_disable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > + > +DEFINE_EVENT(clock, clock_set_rate, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > + > +/* > + * The power domain events are used for power domains transitions > + */ > +DECLARE_EVENT_CLASS(power_domain, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > +), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(power_domain, power_domain_target, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/regulator.h b/instrumentation/events/lttng-module/regulator.h > new file mode 100644 > index 0000000..e94da7c > --- /dev/null > +++ b/instrumentation/events/lttng-module/regulator.h > @@ -0,0 +1,141 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM regulator > + > +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_REGULATOR_H > + > +#include > +#include > + > +/* > + * Events which just log themselves and the regulator name for enable/disable > + * type tracking. > + */ > +DECLARE_EVENT_CLASS(regulator_basic, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + ), > + > + TP_printk("name=%s", __get_str(name)) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_enable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_enable_delay, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_enable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_disable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_disable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +/* > + * Events that take a range of numerical values, mostly for voltages > + * and so on. > + */ > +DECLARE_EVENT_CLASS(regulator_range, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( int, min ) > + __field( int, max ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(min, min); > + tp_assign(max, max); > + ), > + > + TP_printk("name=%s (%d-%d)", __get_str(name), > + (int)__entry->min, (int)__entry->max) > +) > + > +DEFINE_EVENT(regulator_range, regulator_set_voltage, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max) > + > +) > + > + > +/* > + * Events that take a single value, mostly for readback and refcounts. > + */ > +DECLARE_EVENT_CLASS(regulator_value, > + > + TP_PROTO(const char *name, unsigned int val), > + > + TP_ARGS(name, val), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(val, val); > + ), > + > + TP_printk("name=%s, val=%u", __get_str(name), > + (int)__entry->val) > +) > + > +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, > + > + TP_PROTO(const char *name, unsigned int value), > + > + TP_ARGS(name, value) > + > +) > + > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h > new file mode 100644 > index 0000000..27362f8 > --- /dev/null > +++ b/instrumentation/events/lttng-module/scsi.h > @@ -0,0 +1,369 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM scsi > + > +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SCSI_H > + > +#include > +#include > +#include > +#include > + > +#ifndef _TRACE_SCSI_DEF > +#define _TRACE_SCSI_DEF > + > +#define scsi_opcode_name(opcode) { opcode, #opcode } > +#define show_opcode_name(val) \ > + __print_symbolic(val, \ > + scsi_opcode_name(TEST_UNIT_READY), \ > + scsi_opcode_name(REZERO_UNIT), \ > + scsi_opcode_name(REQUEST_SENSE), \ > + scsi_opcode_name(FORMAT_UNIT), \ > + scsi_opcode_name(READ_BLOCK_LIMITS), \ > + scsi_opcode_name(REASSIGN_BLOCKS), \ > + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ > + scsi_opcode_name(READ_6), \ > + scsi_opcode_name(WRITE_6), \ > + scsi_opcode_name(SEEK_6), \ > + scsi_opcode_name(READ_REVERSE), \ > + scsi_opcode_name(WRITE_FILEMARKS), \ > + scsi_opcode_name(SPACE), \ > + scsi_opcode_name(INQUIRY), \ > + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ > + scsi_opcode_name(MODE_SELECT), \ > + scsi_opcode_name(RESERVE), \ > + scsi_opcode_name(RELEASE), \ > + scsi_opcode_name(COPY), \ > + scsi_opcode_name(ERASE), \ > + scsi_opcode_name(MODE_SENSE), \ > + scsi_opcode_name(START_STOP), \ > + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ > + scsi_opcode_name(SEND_DIAGNOSTIC), \ > + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ > + scsi_opcode_name(SET_WINDOW), \ > + scsi_opcode_name(READ_CAPACITY), \ > + scsi_opcode_name(READ_10), \ > + scsi_opcode_name(WRITE_10), \ > + scsi_opcode_name(SEEK_10), \ > + scsi_opcode_name(POSITION_TO_ELEMENT), \ > + scsi_opcode_name(WRITE_VERIFY), \ > + scsi_opcode_name(VERIFY), \ > + scsi_opcode_name(SEARCH_HIGH), \ > + scsi_opcode_name(SEARCH_EQUAL), \ > + scsi_opcode_name(SEARCH_LOW), \ > + scsi_opcode_name(SET_LIMITS), \ > + scsi_opcode_name(PRE_FETCH), \ > + scsi_opcode_name(READ_POSITION), \ > + scsi_opcode_name(SYNCHRONIZE_CACHE), \ > + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ > + scsi_opcode_name(READ_DEFECT_DATA), \ > + scsi_opcode_name(MEDIUM_SCAN), \ > + scsi_opcode_name(COMPARE), \ > + scsi_opcode_name(COPY_VERIFY), \ > + scsi_opcode_name(WRITE_BUFFER), \ > + scsi_opcode_name(READ_BUFFER), \ > + scsi_opcode_name(UPDATE_BLOCK), \ > + scsi_opcode_name(READ_LONG), \ > + scsi_opcode_name(WRITE_LONG), \ > + scsi_opcode_name(CHANGE_DEFINITION), \ > + scsi_opcode_name(WRITE_SAME), \ > + scsi_opcode_name(UNMAP), \ > + scsi_opcode_name(READ_TOC), \ > + scsi_opcode_name(LOG_SELECT), \ > + scsi_opcode_name(LOG_SENSE), \ > + scsi_opcode_name(XDWRITEREAD_10), \ > + scsi_opcode_name(MODE_SELECT_10), \ > + scsi_opcode_name(RESERVE_10), \ > + scsi_opcode_name(RELEASE_10), \ > + scsi_opcode_name(MODE_SENSE_10), \ > + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ > + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ > + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ > + scsi_opcode_name(REPORT_LUNS), \ > + scsi_opcode_name(MAINTENANCE_IN), \ > + scsi_opcode_name(MAINTENANCE_OUT), \ > + scsi_opcode_name(MOVE_MEDIUM), \ > + scsi_opcode_name(EXCHANGE_MEDIUM), \ > + scsi_opcode_name(READ_12), \ > + scsi_opcode_name(WRITE_12), \ > + scsi_opcode_name(WRITE_VERIFY_12), \ > + scsi_opcode_name(SEARCH_HIGH_12), \ > + scsi_opcode_name(SEARCH_EQUAL_12), \ > + scsi_opcode_name(SEARCH_LOW_12), \ > + scsi_opcode_name(READ_ELEMENT_STATUS), \ > + scsi_opcode_name(SEND_VOLUME_TAG), \ > + scsi_opcode_name(WRITE_LONG_2), \ > + scsi_opcode_name(READ_16), \ > + scsi_opcode_name(WRITE_16), \ > + scsi_opcode_name(VERIFY_16), \ > + scsi_opcode_name(WRITE_SAME_16), \ > + scsi_opcode_name(SERVICE_ACTION_IN), \ > + scsi_opcode_name(SAI_READ_CAPACITY_16), \ > + scsi_opcode_name(SAI_GET_LBA_STATUS), \ > + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ > + scsi_opcode_name(MO_SET_TARGET_PGS), \ > + scsi_opcode_name(READ_32), \ > + scsi_opcode_name(WRITE_32), \ > + scsi_opcode_name(WRITE_SAME_32), \ > + scsi_opcode_name(ATA_16), \ > + scsi_opcode_name(ATA_12)) > + > +#define scsi_hostbyte_name(result) { result, #result } > +#define show_hostbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_hostbyte_name(DID_OK), \ > + scsi_hostbyte_name(DID_NO_CONNECT), \ > + scsi_hostbyte_name(DID_BUS_BUSY), \ > + scsi_hostbyte_name(DID_TIME_OUT), \ > + scsi_hostbyte_name(DID_BAD_TARGET), \ > + scsi_hostbyte_name(DID_ABORT), \ > + scsi_hostbyte_name(DID_PARITY), \ > + scsi_hostbyte_name(DID_ERROR), \ > + scsi_hostbyte_name(DID_RESET), \ > + scsi_hostbyte_name(DID_BAD_INTR), \ > + scsi_hostbyte_name(DID_PASSTHROUGH), \ > + scsi_hostbyte_name(DID_SOFT_ERROR), \ > + scsi_hostbyte_name(DID_IMM_RETRY), \ > + scsi_hostbyte_name(DID_REQUEUE), \ > + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ > + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) > + > +#define scsi_driverbyte_name(result) { result, #result } > +#define show_driverbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_driverbyte_name(DRIVER_OK), \ > + scsi_driverbyte_name(DRIVER_BUSY), \ > + scsi_driverbyte_name(DRIVER_SOFT), \ > + scsi_driverbyte_name(DRIVER_MEDIA), \ > + scsi_driverbyte_name(DRIVER_ERROR), \ > + scsi_driverbyte_name(DRIVER_INVALID), \ > + scsi_driverbyte_name(DRIVER_TIMEOUT), \ > + scsi_driverbyte_name(DRIVER_HARD), \ > + scsi_driverbyte_name(DRIVER_SENSE)) > + > +#define scsi_msgbyte_name(result) { result, #result } > +#define show_msgbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_msgbyte_name(COMMAND_COMPLETE), \ > + scsi_msgbyte_name(EXTENDED_MESSAGE), \ > + scsi_msgbyte_name(SAVE_POINTERS), \ > + scsi_msgbyte_name(RESTORE_POINTERS), \ > + scsi_msgbyte_name(DISCONNECT), \ > + scsi_msgbyte_name(INITIATOR_ERROR), \ > + scsi_msgbyte_name(ABORT_TASK_SET), \ > + scsi_msgbyte_name(MESSAGE_REJECT), \ > + scsi_msgbyte_name(NOP), \ > + scsi_msgbyte_name(MSG_PARITY_ERROR), \ > + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ > + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ > + scsi_msgbyte_name(TARGET_RESET), \ > + scsi_msgbyte_name(ABORT_TASK), \ > + scsi_msgbyte_name(CLEAR_TASK_SET), \ > + scsi_msgbyte_name(INITIATE_RECOVERY), \ > + scsi_msgbyte_name(RELEASE_RECOVERY), \ > + scsi_msgbyte_name(CLEAR_ACA), \ > + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ > + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ > + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ > + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ > + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ > + scsi_msgbyte_name(ACA), \ > + scsi_msgbyte_name(QAS_REQUEST), \ > + scsi_msgbyte_name(BUS_DEVICE_RESET), \ > + scsi_msgbyte_name(ABORT)) > + > +#define scsi_statusbyte_name(result) { result, #result } > +#define show_statusbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_statusbyte_name(SAM_STAT_GOOD), \ > + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ > + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_BUSY), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ > + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ > + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ > + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ > + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) > + > +#define scsi_prot_op_name(result) { result, #result } > +#define show_prot_op_name(val) \ > + __print_symbolic(val, \ > + scsi_prot_op_name(SCSI_PROT_NORMAL), \ > + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) > + > +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); > +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) > +#endif > + > +TRACE_EVENT(scsi_dispatch_cmd_start, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, cmd->device->host->host_no); > + tp_assign(channel, cmd->device->channel); > + tp_assign(id, cmd->device->id); > + tp_assign(lun, cmd->device->lun); > + tp_assign(opcode, cmd->cmnd[0]); > + tp_assign(cmd_len, cmd->cmd_len); > + tp_assign(data_sglen, scsi_sg_count(cmd)); > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > + tp_assign(prot_op, scsi_get_prot_op(cmd)); > + tp_memcpy_dyn(cmnd, cmd->cmnd); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) > +) > + > +TRACE_EVENT(scsi_dispatch_cmd_error, > + > + TP_PROTO(struct scsi_cmnd *cmd, int rtn), > + > + TP_ARGS(cmd, rtn), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, rtn ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, cmd->device->host->host_no); > + tp_assign(channel, cmd->device->channel); > + tp_assign(id, cmd->device->id); > + tp_assign(lun, cmd->device->lun); > + tp_assign(rtn, rtn); > + tp_assign(opcode, cmd->cmnd[0]); > + tp_assign(cmd_len, cmd->cmd_len); > + tp_assign(data_sglen, scsi_sg_count(cmd)); > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > + tp_assign(prot_op, scsi_get_prot_op(cmd)); > + tp_memcpy_dyn(cmnd, cmd->cmnd); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + __entry->rtn) > +) > + > +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, result ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, cmd->device->host->host_no); > + tp_assign(channel, cmd->device->channel); > + tp_assign(id, cmd->device->id); > + tp_assign(lun, cmd->device->lun); > + tp_assign(result, cmd->result); > + tp_assign(opcode, cmd->cmnd[0]); > + tp_assign(cmd_len, cmd->cmd_len); > + tp_assign(data_sglen, scsi_sg_count(cmd)); > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > + tp_assign(prot_op, scsi_get_prot_op(cmd)); > + tp_memcpy_dyn(cmnd, cmd->cmnd); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ > + "%s host=%s message=%s status=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + show_driverbyte_name(((__entry->result) >> 24) & 0xff), > + show_hostbyte_name(((__entry->result) >> 16) & 0xff), > + show_msgbyte_name(((__entry->result) >> 8) & 0xff), > + show_statusbyte_name(__entry->result & 0xff)) > +) > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)) > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)) > + > +TRACE_EVENT(scsi_eh_wakeup, > + > + TP_PROTO(struct Scsi_Host *shost), > + > + TP_ARGS(shost), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, shost->host_no); > + ), > + > + TP_printk("host_no=%u", __entry->host_no) > +) > + > +#endif /* _TRACE_SCSI_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/skb.h b/instrumentation/events/lttng-module/skb.h > new file mode 100644 > index 0000000..9a79449 > --- /dev/null > +++ b/instrumentation/events/lttng-module/skb.h > @@ -0,0 +1,75 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM skb > + > +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SKB_H > + > +#include > +#include > +#include > + > +/* > + * Tracepoint for free an sk_buff: > + */ > +TRACE_EVENT(kfree_skb, > + > + TP_PROTO(struct sk_buff *skb, void *location), > + > + TP_ARGS(skb, location), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( void *, location ) > + __field( unsigned short, protocol ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(location, location); > + tp_assign(protocol, ntohs(skb->protocol)); > + ), > + > + TP_printk("skbaddr=%p protocol=%u location=%p", > + __entry->skbaddr, __entry->protocol, __entry->location) > +) > + > +TRACE_EVENT(consume_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + ), > + > + TP_printk("skbaddr=%p", __entry->skbaddr) > +) > + > +TRACE_EVENT(skb_copy_datagram_iovec, > + > + TP_PROTO(const struct sk_buff *skb, int len), > + > + TP_ARGS(skb, len), > + > + TP_STRUCT__entry( > + __field( const void *, skbaddr ) > + __field( int, len ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, len); > + ), > + > + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) > +) > + > +#endif /* _TRACE_SKB_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h > new file mode 100644 > index 0000000..246ea58 > --- /dev/null > +++ b/instrumentation/events/lttng-module/sock.h > @@ -0,0 +1,68 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM sock > + > +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SOCK_H > + > +#include > +#include > + > +TRACE_EVENT(sock_rcvqueue_full, > + > + TP_PROTO(struct sock *sk, struct sk_buff *skb), > + > + TP_ARGS(sk, skb), > + > + TP_STRUCT__entry( > + __field(int, rmem_alloc) > + __field(unsigned int, truesize) > + __field(int, sk_rcvbuf) > + ), > + > + TP_fast_assign( > + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > + tp_assign(truesize, skb->truesize); > + tp_assign(sk_rcvbuf, sk->sk_rcvbuf); > + ), > + > + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", > + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) > +) > + > +TRACE_EVENT(sock_exceed_buf_limit, > + > + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), > + > + TP_ARGS(sk, prot, allocated), > + > + TP_STRUCT__entry( > + __string(name, prot->name) > + __field(long *, sysctl_mem) > + __field(long, allocated) > + __field(int, sysctl_rmem) > + __field(int, rmem_alloc) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, prot->name); > + tp_assign(sysctl_mem, prot->sysctl_mem); > + tp_assign(allocated, allocated); > + tp_assign(sysctl_rmem, prot->sysctl_rmem[0]); > + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > + ), > + > + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " > + "sysctl_rmem=%d rmem_alloc=%d", > + __entry->name, > + __entry->sysctl_mem[0], > + __entry->sysctl_mem[1], > + __entry->sysctl_mem[2], > + __entry->allocated, > + __entry->sysctl_rmem, > + __entry->rmem_alloc) > +) > + > +#endif /* _TRACE_SOCK_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/udp.h b/instrumentation/events/lttng-module/udp.h > new file mode 100644 > index 0000000..304ea95 > --- /dev/null > +++ b/instrumentation/events/lttng-module/udp.h > @@ -0,0 +1,32 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM udp > + > +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_UDP_H > + > +#include > +#include > + > +TRACE_EVENT(udp_fail_queue_rcv_skb, > + > + TP_PROTO(int rc, struct sock *sk), > + > + TP_ARGS(rc, sk), > + > + TP_STRUCT__entry( > + __field(int, rc) > + __field(__u16, lport) > + ), > + > + TP_fast_assign( > + tp_assign(rc, rc); > + tp_assign(lport, inet_sk(sk)->inet_num); > + ), > + > + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) > +) > + > +#endif /* _TRACE_UDP_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h > new file mode 100644 > index 0000000..aa022e2 > --- /dev/null > +++ b/instrumentation/events/lttng-module/vmscan.h > @@ -0,0 +1,499 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM vmscan > + > +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_VMSCAN_H > + > +TRACE_EVENT(mm_vmscan_kswapd_sleep, > + > + TP_PROTO(int nid), > + > + TP_ARGS(nid), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + ), > + > + TP_printk("nid=%d", __entry->nid) > +) > + > +TRACE_EVENT(mm_vmscan_kswapd_wake, > + > + TP_PROTO(int nid, int order), > + > + TP_ARGS(nid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + tp_assign(order, order); > + ), > + > + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) > +) > + > +TRACE_EVENT(mm_vmscan_wakeup_kswapd, > + > + TP_PROTO(int nid, int zid, int order), > + > + TP_ARGS(nid, zid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, zid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + tp_assign(zid, zid); > + tp_assign(order, order); > + ), > + > + TP_printk("nid=%d zid=%d order=%d", > + __entry->nid, > + __entry->zid, > + __entry->order) > +) > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags), > + > + TP_STRUCT__entry( > + __field( int, order ) > + __field( int, may_writepage ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + tp_assign(order, order); > + tp_assign(may_writepage, may_writepage); > + tp_assign(gfp_flags, gfp_flags); > + ), > + > + TP_printk("order=%d may_writepage=%d gfp_flags=%s", > + __entry->order, > + __entry->may_writepage, > + show_gfp_flags(__entry->gfp_flags)) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +) > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed), > + > + TP_STRUCT__entry( > + __field( unsigned long, nr_reclaimed ) > + ), > + > + TP_fast_assign( > + tp_assign(nr_reclaimed, nr_reclaimed); > + ), > + > + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +) > + > +TRACE_EVENT(mm_shrink_slab_start, > + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, > + long nr_objects_to_shrink, unsigned long pgs_scanned, > + unsigned long lru_pgs, unsigned long cache_items, > + unsigned long long delta, unsigned long total_scan), > + > + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, > + cache_items, delta, total_scan), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, nr_objects_to_shrink) > + __field(gfp_t, gfp_flags) > + __field(unsigned long, pgs_scanned) > + __field(unsigned long, lru_pgs) > + __field(unsigned long, cache_items) > + __field(unsigned long long, delta) > + __field(unsigned long, total_scan) > + ), > + > + TP_fast_assign( > + tp_assign(shr,shr); > + tp_assign(shrink, shr->shrink); > + tp_assign(nr_objects_to_shrink, nr_objects_to_shrink); > + tp_assign(gfp_flags, sc->gfp_mask); > + tp_assign(pgs_scanned, pgs_scanned); > + tp_assign(lru_pgs, lru_pgs); > + tp_assign(cache_items, cache_items); > + tp_assign(delta, delta); > + tp_assign(total_scan, total_scan); > + ), > + > + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", > + __entry->shrink, > + __entry->shr, > + __entry->nr_objects_to_shrink, > + show_gfp_flags(__entry->gfp_flags), > + __entry->pgs_scanned, > + __entry->lru_pgs, > + __entry->cache_items, > + __entry->delta, > + __entry->total_scan) > +) > + > +TRACE_EVENT(mm_shrink_slab_end, > + TP_PROTO(struct shrinker *shr, int shrinker_retval, > + long unused_scan_cnt, long new_scan_cnt), > + > + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, unused_scan) > + __field(long, new_scan) > + __field(int, retval) > + __field(long, total_scan) > + ), > + > + TP_fast_assign( > + tp_assign(shr, shr); > + tp_assign(shrink, shr->shrink); > + tp_assign(unused_scan, unused_scan_cnt); > + tp_assign(new_scan, new_scan_cnt); > + tp_assign(retval, shrinker_retval); > + tp_assign(total_scan, new_scan_cnt - unused_scan_cnt); > + ), > + > + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", > + __entry->shrink, > + __entry->shr, > + __entry->unused_scan, > + __entry->new_scan, > + __entry->total_scan, > + __entry->retval) > +) > + > +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + isolate_mode_t isolate_mode), > +#else > + isolate_mode_t isolate_mode, > + int file), > +#endif > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), > +#else > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file), > +#endif > + > + TP_STRUCT__entry( > + __field(int, order) > + __field(unsigned long, nr_requested) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_taken) > + __field(unsigned long, nr_lumpy_taken) > + __field(unsigned long, nr_lumpy_dirty) > + __field(unsigned long, nr_lumpy_failed) > + __field(isolate_mode_t, isolate_mode) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > + __field(int, file) > +#endif > + ), > + > + TP_fast_assign( > + tp_assign(order, order); > + tp_assign(nr_requested, nr_requested); > + tp_assign(nr_scanned, nr_scanned); > + tp_assign(nr_taken, nr_taken); > + tp_assign(nr_lumpy_taken, nr_lumpy_taken); > + tp_assign(nr_lumpy_dirty, nr_lumpy_dirty); > + tp_assign(nr_lumpy_failed, nr_lumpy_failed); > + tp_assign(isolate_mode, isolate_mode); > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > + tp_assign(file, file); > +#endif > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", > +#else > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", > +#endif > + __entry->isolate_mode, > + __entry->order, > + __entry->nr_requested, > + __entry->nr_scanned, > + __entry->nr_taken, > + __entry->nr_lumpy_taken, > + __entry->nr_lumpy_dirty, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + __entry->nr_lumpy_failed) > +#else > + __entry->nr_lumpy_failed, > + __entry->file) > +#endif > +) > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > +#endif > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + isolate_mode_t isolate_mode), > +#else > + isolate_mode_t isolate_mode, > + int file), > +#endif > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) > +#else > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > +#endif > + > +) > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > +#endif > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + isolate_mode_t isolate_mode), > +#else > + isolate_mode_t isolate_mode, > + int file), > +#endif > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) > +#else > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > +#endif > + > +) > + > +TRACE_EVENT(mm_vmscan_writepage, > + > + TP_PROTO(struct page *page, > + int reclaim_flags), > + > + TP_ARGS(page, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(struct page *, page) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(reclaim_flags, reclaim_flags); > + ), > + > + TP_printk("page=%p pfn=%lu flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + show_reclaim_flags(__entry->reclaim_flags)) > +) > + > +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > + > + TP_PROTO(int nid, int zid, > + unsigned long nr_scanned, unsigned long nr_reclaimed, > + int priority, int reclaim_flags), > + > + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(int, nid) > + __field(int, zid) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_reclaimed) > + __field(int, priority) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + tp_assign(zid, zid); > + tp_assign(nr_scanned, nr_scanned); > + tp_assign(nr_reclaimed, nr_reclaimed); > + tp_assign(priority, priority); > + tp_assign(reclaim_flags, reclaim_flags); > + ), > + > + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", > + __entry->nid, __entry->zid, > + __entry->nr_scanned, __entry->nr_reclaimed, > + __entry->priority, > + show_reclaim_flags(__entry->reclaim_flags)) > +) > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + > +TRACE_EVENT(replace_swap_token, > + TP_PROTO(struct mm_struct *old_mm, > + struct mm_struct *new_mm), > + > + TP_ARGS(old_mm, new_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, old_mm) > + __field(unsigned int, old_prio) > + __field(struct mm_struct*, new_mm) > + __field(unsigned int, new_prio) > + ), > + > + TP_fast_assign( > + tp_assign(old_mm, old_mm); > + tp_assign(old_prio, old_mm ? old_mm->token_priority : 0); > + tp_assign(new_mm, new_mm); > + tp_assign(new_prio, new_mm->token_priority); > + ), > + > + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", > + __entry->old_mm, __entry->old_prio, > + __entry->new_mm, __entry->new_prio) > +) > + > +DECLARE_EVENT_CLASS(put_swap_token_template, > + TP_PROTO(struct mm_struct *swap_token_mm), > + > + TP_ARGS(swap_token_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, swap_token_mm) > + ), > + > + TP_fast_assign( > + tp_assign(swap_token_mm, swap_token_mm); > + ), > + > + TP_printk("token_mm=%p", __entry->swap_token_mm) > +) > + > +DEFINE_EVENT(put_swap_token_template, put_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm) > +) > + > +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm), > + TP_CONDITION(swap_token_mm != NULL) > +) > + > +TRACE_EVENT_CONDITION(update_swap_token_priority, > + TP_PROTO(struct mm_struct *mm, > + unsigned int old_prio, > + struct mm_struct *swap_token_mm), > + > + TP_ARGS(mm, old_prio, swap_token_mm), > + > + TP_CONDITION(mm->token_priority != old_prio), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, mm) > + __field(unsigned int, old_prio) > + __field(unsigned int, new_prio) > + __field(struct mm_struct*, swap_token_mm) > + __field(unsigned int, swap_token_prio) > + ), > + > + TP_fast_assign( > + tp_assign(mm, mm); > + tp_assign(old_prio, old_prio); > + tp_assign(new_prio, mm->token_priority); > + tp_assign(swap_token_mm, swap_token_mm); > + tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0); > + ), > + > + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", > + __entry->mm, __entry->old_prio, __entry->new_prio, > + __entry->swap_token_mm, __entry->swap_token_prio) > +) > + > +#endif > + > +#endif /* _TRACE_VMSCAN_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/mainline/asoc.h b/instrumentation/events/mainline/asoc.h > new file mode 100644 > index 0000000..ab26f8a > --- /dev/null > +++ b/instrumentation/events/mainline/asoc.h > @@ -0,0 +1,330 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM asoc > + > +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_ASOC_H > + > +#include > +#include > + > +struct snd_soc_jack; > +struct snd_soc_codec; > +struct snd_soc_platform; > +struct snd_soc_card; > +struct snd_soc_dapm_widget; > + > +/* > + * Log register events > + */ > +DECLARE_EVENT_CLASS(snd_soc_reg, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, codec->name); > + __entry->id = codec->id; > + __entry->reg = reg; > + __entry->val = val; > + ), > + > + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +); > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_preg, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val), > + > + TP_STRUCT__entry( > + __string( name, platform->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, platform->name); > + __entry->id = platform->id; > + __entry->reg = reg; > + __entry->val = val; > + ), > + > + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +); > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_card, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, card->name); > + __entry->val = val; > + ), > + > + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +); > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, card->name); > + ), > + > + TP_printk("card=%s", __get_str(name)) > +); > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +); > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val), > + > + TP_STRUCT__entry( > + __string( name, w->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, w->name); > + __entry->val = val; > + ), > + > + TP_printk("widget=%s val=%d", __get_str(name), > + (int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +); > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +); > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +); > + > +TRACE_EVENT(snd_soc_dapm_walk_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, power_checks ) > + __field( int, path_checks ) > + __field( int, neighbour_checks ) > + ), > + > + TP_fast_assign( > + __assign_str(name, card->name); > + __entry->power_checks = card->dapm_stats.power_checks; > + __entry->path_checks = card->dapm_stats.path_checks; > + __entry->neighbour_checks = card->dapm_stats.neighbour_checks; > + ), > + > + TP_printk("%s: checks %d power, %d path, %d neighbour", > + __get_str(name), (int)__entry->power_checks, > + (int)__entry->path_checks, (int)__entry->neighbour_checks) > +); > + > +TRACE_EVENT(snd_soc_jack_irq, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + ), > + > + TP_printk("%s", __get_str(name)) > +); > + > +TRACE_EVENT(snd_soc_jack_report, > + > + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), > + > + TP_ARGS(jack, mask, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, mask ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, jack->jack->name); > + __entry->mask = mask; > + __entry->val = val; > + ), > + > + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, > + (int)__entry->mask) > +); > + > +TRACE_EVENT(snd_soc_jack_notify, > + > + TP_PROTO(struct snd_soc_jack *jack, int val), > + > + TP_ARGS(jack, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, jack->jack->name); > + __entry->val = val; > + ), > + > + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) > +); > + > +TRACE_EVENT(snd_soc_cache_sync, > + > + TP_PROTO(struct snd_soc_codec *codec, const char *type, > + const char *status), > + > + TP_ARGS(codec, type, status), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __string( status, status ) > + __string( type, type ) > + __field( int, id ) > + ), > + > + TP_fast_assign( > + __assign_str(name, codec->name); > + __assign_str(status, status); > + __assign_str(type, type); > + __entry->id = codec->id; > + ), > + > + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), > + (int)__entry->id, __get_str(type), __get_str(status)) > +); > + > +#endif /* _TRACE_ASOC_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/ext3.h b/instrumentation/events/mainline/ext3.h > new file mode 100644 > index 0000000..7b53c05 > --- /dev/null > +++ b/instrumentation/events/mainline/ext3.h > @@ -0,0 +1,864 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM ext3 > + > +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_EXT3_H > + > +#include > + > +TRACE_EVENT(ext3_free_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( uid_t, uid ) > + __field( gid_t, gid ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->mode = inode->i_mode; > + __entry->uid = inode->i_uid; > + __entry->gid = inode->i_gid; > + __entry->blocks = inode->i_blocks; > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->uid, __entry->gid, > + (unsigned long) __entry->blocks) > +); > + > +TRACE_EVENT(ext3_request_inode, > + TP_PROTO(struct inode *dir, int mode), > + > + TP_ARGS(dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + __entry->dev = dir->i_sb->s_dev; > + __entry->dir = dir->i_ino; > + __entry->mode = mode; > + ), > + > + TP_printk("dev %d,%d dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->dir, __entry->mode) > +); > + > +TRACE_EVENT(ext3_allocate_inode, > + TP_PROTO(struct inode *inode, struct inode *dir, int mode), > + > + TP_ARGS(inode, dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->dir = dir->i_ino; > + __entry->mode = mode; > + ), > + > + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->dir, __entry->mode) > +); > + > +TRACE_EVENT(ext3_evict_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, nlink ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->nlink = inode->i_nlink; > + ), > + > + TP_printk("dev %d,%d ino %lu nlink %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->nlink) > +); > + > +TRACE_EVENT(ext3_drop_inode, > + TP_PROTO(struct inode *inode, int drop), > + > + TP_ARGS(inode, drop), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, drop ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->drop = drop; > + ), > + > + TP_printk("dev %d,%d ino %lu drop %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->drop) > +); > + > +TRACE_EVENT(ext3_mark_inode_dirty, > + TP_PROTO(struct inode *inode, unsigned long IP), > + > + TP_ARGS(inode, IP), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field(unsigned long, ip ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->ip = IP; > + ), > + > + TP_printk("dev %d,%d ino %lu caller %pF", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (void *)__entry->ip) > +); > + > +TRACE_EVENT(ext3_write_begin, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int flags), > + > + TP_ARGS(inode, pos, len, flags), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, flags ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->pos = pos; > + __entry->len = len; > + __entry->flags = flags; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->flags) > +); > + > +DECLARE_EVENT_CLASS(ext3__write_end, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, copied ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->pos = pos; > + __entry->len = len; > + __entry->copied = copied; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->copied) > +); > + > +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +); > + > +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +); > + > +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +); > + > +DECLARE_EVENT_CLASS(ext3__page_op, > + TP_PROTO(struct page *page), > + > + TP_ARGS(page), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( pgoff_t, index ) > + > + ), > + > + TP_fast_assign( > + __entry->index = page->index; > + __entry->ino = page->mapping->host->i_ino; > + __entry->dev = page->mapping->host->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->index) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_readpage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_releasepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +TRACE_EVENT(ext3_invalidatepage, > + TP_PROTO(struct page *page, unsigned long offset), > + > + TP_ARGS(page, offset), > + > + TP_STRUCT__entry( > + __field( pgoff_t, index ) > + __field( unsigned long, offset ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + > + ), > + > + TP_fast_assign( > + __entry->index = page->index; > + __entry->offset = offset; > + __entry->ino = page->mapping->host->i_ino; > + __entry->dev = page->mapping->host->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->index, __entry->offset) > +); > + > +TRACE_EVENT(ext3_discard_blocks, > + TP_PROTO(struct super_block *sb, unsigned long blk, > + unsigned long count), > + > + TP_ARGS(sb, blk, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, blk ) > + __field( unsigned long, count ) > + > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->blk = blk; > + __entry->count = count; > + ), > + > + TP_printk("dev %d,%d blk %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->blk, __entry->count) > +); > + > +TRACE_EVENT(ext3_request_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count), > + > + TP_ARGS(inode, goal, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->count = count; > + __entry->goal = goal; > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->goal) > +); > + > +TRACE_EVENT(ext3_allocate_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count, unsigned long block), > + > + TP_ARGS(inode, goal, count, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->block = block; > + __entry->count = count; > + __entry->goal = goal; > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->block, > + __entry->goal) > +); > + > +TRACE_EVENT(ext3_free_blocks, > + TP_PROTO(struct inode *inode, unsigned long block, > + unsigned long count), > + > + TP_ARGS(inode, block, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->mode = inode->i_mode; > + __entry->block = block; > + __entry->count = count; > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->block, __entry->count) > +); > + > +TRACE_EVENT(ext3_sync_file_enter, > + TP_PROTO(struct file *file, int datasync), > + > + TP_ARGS(file, datasync), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, parent ) > + __field( int, datasync ) > + ), > + > + TP_fast_assign( > + struct dentry *dentry = file->f_path.dentry; > + > + __entry->dev = dentry->d_inode->i_sb->s_dev; > + __entry->ino = dentry->d_inode->i_ino; > + __entry->datasync = datasync; > + __entry->parent = dentry->d_parent->d_inode->i_ino; > + ), > + > + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->parent, __entry->datasync) > +); > + > +TRACE_EVENT(ext3_sync_file_exit, > + TP_PROTO(struct inode *inode, int ret), > + > + TP_ARGS(inode, ret), > + > + TP_STRUCT__entry( > + __field( int, ret ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->ret = ret; > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +); > + > +TRACE_EVENT(ext3_sync_fs, > + TP_PROTO(struct super_block *sb, int wait), > + > + TP_ARGS(sb, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->wait = wait; > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +); > + > +TRACE_EVENT(ext3_rsv_window_add, > + TP_PROTO(struct super_block *sb, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->start = rsv_node->rsv_window._rsv_start; > + __entry->end = rsv_node->rsv_window._rsv_end; > + ), > + > + TP_printk("dev %d,%d start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->start, __entry->end) > +); > + > +TRACE_EVENT(ext3_discard_reservation, > + TP_PROTO(struct inode *inode, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(inode, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->start = rsv_node->rsv_window._rsv_start; > + __entry->end = rsv_node->rsv_window._rsv_end; > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long)__entry->ino, __entry->start, > + __entry->end) > +); > + > +TRACE_EVENT(ext3_alloc_new_reservation, > + TP_PROTO(struct super_block *sb, unsigned long goal), > + > + TP_ARGS(sb, goal), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->goal = goal; > + ), > + > + TP_printk("dev %d,%d goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->goal) > +); > + > +TRACE_EVENT(ext3_reserved, > + TP_PROTO(struct super_block *sb, unsigned long block, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, block, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, block ) > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->block = block; > + __entry->start = rsv_node->rsv_window._rsv_start; > + __entry->end = rsv_node->rsv_window._rsv_end; > + __entry->dev = sb->s_dev; > + ), > + > + TP_printk("dev %d,%d block %lu, start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->block, __entry->start, __entry->end) > +); > + > +TRACE_EVENT(ext3_forget, > + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), > + > + TP_ARGS(inode, is_metadata, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( int, is_metadata ) > + __field( unsigned long, block ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->mode = inode->i_mode; > + __entry->is_metadata = is_metadata; > + __entry->block = block; > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->is_metadata, __entry->block) > +); > + > +TRACE_EVENT(ext3_read_block_bitmap, > + TP_PROTO(struct super_block *sb, unsigned int group), > + > + TP_ARGS(sb, group), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( __u32, group ) > + > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->group = group; > + ), > + > + TP_printk("dev %d,%d group %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->group) > +); > + > +TRACE_EVENT(ext3_direct_IO_enter, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), > + > + TP_ARGS(inode, offset, len, rw), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->pos = offset; > + __entry->len = len; > + __entry->rw = rw; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw) > +); > + > +TRACE_EVENT(ext3_direct_IO_exit, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, > + int rw, int ret), > + > + TP_ARGS(inode, offset, len, rw, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->pos = offset; > + __entry->len = len; > + __entry->rw = rw; > + __entry->ret = ret; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw, __entry->ret) > +); > + > +TRACE_EVENT(ext3_unlink_enter, > + TP_PROTO(struct inode *parent, struct dentry *dentry), > + > + TP_ARGS(parent, dentry), > + > + TP_STRUCT__entry( > + __field( ino_t, parent ) > + __field( ino_t, ino ) > + __field( loff_t, size ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->parent = parent->i_ino; > + __entry->ino = dentry->d_inode->i_ino; > + __entry->size = dentry->d_inode->i_size; > + __entry->dev = dentry->d_inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu size %lld parent %ld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long)__entry->size, > + (unsigned long) __entry->parent) > +); > + > +TRACE_EVENT(ext3_unlink_exit, > + TP_PROTO(struct dentry *dentry, int ret), > + > + TP_ARGS(dentry, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ino = dentry->d_inode->i_ino; > + __entry->dev = dentry->d_inode->i_sb->s_dev; > + __entry->ret = ret; > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +); > + > +DECLARE_EVENT_CLASS(ext3__truncate, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->blocks = inode->i_blocks; > + ), > + > + TP_printk("dev %d,%d ino %lu blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) > +); > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +); > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +); > + > +TRACE_EVENT(ext3_get_blocks_enter, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long len, int create), > + > + TP_ARGS(inode, lblk, len, create), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, len ) > + __field( int, create ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->lblk = lblk; > + __entry->len = len; > + __entry->create = create; > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->len, __entry->create) > +); > + > +TRACE_EVENT(ext3_get_blocks_exit, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long pblk, unsigned long len, int ret), > + > + TP_ARGS(inode, lblk, pblk, len, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, pblk ) > + __field( unsigned long, len ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->lblk = lblk; > + __entry->pblk = pblk; > + __entry->len = len; > + __entry->ret = ret; > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->pblk, > + __entry->len, __entry->ret) > +); > + > +TRACE_EVENT(ext3_load_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +); > + > +#endif /* _TRACE_EXT3_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/fs_ext3.h b/instrumentation/events/mainline/fs_ext3.h > new file mode 100644 > index 0000000..76353e4 > --- /dev/null > +++ b/instrumentation/events/mainline/fs_ext3.h > @@ -0,0 +1,1323 @@ > +/* > + * Written by Stephen C. Tweedie , 1999 > + * > + * Copyright 1998--1999 Red Hat corp --- All Rights Reserved > + * > + * This file is part of the Linux kernel and is made available under > + * the terms of the GNU General Public License, version 2, or at your > + * option, any later version, incorporated herein by reference. > + * > + * Copyright (C) 1992, 1993, 1994, 1995 > + * Remy Card (card at masi.ibp.fr) > + * Laboratoire MASI - Institut Blaise Pascal > + * Universite Pierre et Marie Curie (Paris VI) > + * > + * from > + * > + * linux/include/linux/minix_fs.h > + * > + * Copyright (C) 1991, 1992 Linus Torvalds > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +/* > + * The second extended filesystem constants/structures > + */ > + > +/* > + * Define EXT3FS_DEBUG to produce debug messages > + */ > +#undef EXT3FS_DEBUG > + > +/* > + * Define EXT3_RESERVATION to reserve data blocks for expanding files > + */ > +#define EXT3_DEFAULT_RESERVE_BLOCKS 8 > +/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ > +#define EXT3_MAX_RESERVE_BLOCKS 1027 > +#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 > + > +/* > + * Debug code > + */ > +#ifdef EXT3FS_DEBUG > +#define ext3_debug(f, a...) \ > + do { \ > + printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ > + __FILE__, __LINE__, __func__); \ > + printk (KERN_DEBUG f, ## a); \ > + } while (0) > +#else > +#define ext3_debug(f, a...) do {} while (0) > +#endif > + > +/* > + * Special inodes numbers > + */ > +#define EXT3_BAD_INO 1 /* Bad blocks inode */ > +#define EXT3_ROOT_INO 2 /* Root inode */ > +#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ > +#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ > +#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ > +#define EXT3_JOURNAL_INO 8 /* Journal inode */ > + > +/* First non-reserved inode for old ext3 filesystems */ > +#define EXT3_GOOD_OLD_FIRST_INO 11 > + > +/* > + * Maximal count of links to a file > + */ > +#define EXT3_LINK_MAX 32000 > + > +/* > + * Macro-instructions used to manage several block sizes > + */ > +#define EXT3_MIN_BLOCK_SIZE 1024 > +#define EXT3_MAX_BLOCK_SIZE 65536 > +#define EXT3_MIN_BLOCK_LOG_SIZE 10 > +#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) > +#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) > +#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) > +#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) > +#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) > +#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) > + > +/* > + * Macro-instructions used to manage fragments > + */ > +#define EXT3_MIN_FRAG_SIZE 1024 > +#define EXT3_MAX_FRAG_SIZE 4096 > +#define EXT3_MIN_FRAG_LOG_SIZE 10 > +#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) > +#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) > + > +/* > + * Structure of a blocks group descriptor > + */ > +struct ext3_group_desc > +{ > + __le32 bg_block_bitmap; /* Blocks bitmap block */ > + __le32 bg_inode_bitmap; /* Inodes bitmap block */ > + __le32 bg_inode_table; /* Inodes table block */ > + __le16 bg_free_blocks_count; /* Free blocks count */ > + __le16 bg_free_inodes_count; /* Free inodes count */ > + __le16 bg_used_dirs_count; /* Directories count */ > + __u16 bg_pad; > + __le32 bg_reserved[3]; > +}; > + > +/* > + * Macro-instructions used to manage group descriptors > + */ > +#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) > +#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) > +#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) > +#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) > + > +/* > + * Constants relative to the data blocks > + */ > +#define EXT3_NDIR_BLOCKS 12 > +#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS > +#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1) > +#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1) > +#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1) > + > +/* > + * Inode flags > + */ > +#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */ > +#define EXT3_UNRM_FL 0x00000002 /* Undelete */ > +#define EXT3_COMPR_FL 0x00000004 /* Compress file */ > +#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */ > +#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */ > +#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */ > +#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */ > +#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */ > +/* Reserved for compression usage... */ > +#define EXT3_DIRTY_FL 0x00000100 > +#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ > +#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */ > +#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */ > +/* End compression flags --- maybe not all used */ > +#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */ > +#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ > +#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ > +#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ > +#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ > +#define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ > +#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ > + > +#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ > +#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ > + > +/* Flags that should be inherited by new inodes from their parent. */ > +#define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ > + EXT3_SYNC_FL | EXT3_NODUMP_FL |\ > + EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\ > + EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\ > + EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL) > + > +/* Flags that are appropriate for regular files (all but dir-specific ones). */ > +#define EXT3_REG_FLMASK (~(EXT3_DIRSYNC_FL | EXT3_TOPDIR_FL)) > + > +/* Flags that are appropriate for non-directories/regular files. */ > +#define EXT3_OTHER_FLMASK (EXT3_NODUMP_FL | EXT3_NOATIME_FL) > + > +/* Mask out flags that are inappropriate for the given type of inode. */ > +static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) > +{ > + if (S_ISDIR(mode)) > + return flags; > + else if (S_ISREG(mode)) > + return flags & EXT3_REG_FLMASK; > + else > + return flags & EXT3_OTHER_FLMASK; > +} > + > +/* Used to pass group descriptor data when online resize is done */ > +struct ext3_new_group_input { > + __u32 group; /* Group number for this data */ > + __u32 block_bitmap; /* Absolute block number of block bitmap */ > + __u32 inode_bitmap; /* Absolute block number of inode bitmap */ > + __u32 inode_table; /* Absolute block number of inode table start */ > + __u32 blocks_count; /* Total number of blocks in this group */ > + __u16 reserved_blocks; /* Number of reserved blocks in this group */ > + __u16 unused; > +}; > + > +/* The struct ext3_new_group_input in kernel space, with free_blocks_count */ > +struct ext3_new_group_data { > + __u32 group; > + __u32 block_bitmap; > + __u32 inode_bitmap; > + __u32 inode_table; > + __u32 blocks_count; > + __u16 reserved_blocks; > + __u16 unused; > + __u32 free_blocks_count; > +}; > + > + > +/* > + * ioctl commands > + */ > +#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS > +#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS > +#define EXT3_IOC_GETVERSION _IOR('f', 3, long) > +#define EXT3_IOC_SETVERSION _IOW('f', 4, long) > +#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) > +#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input) > +#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION > +#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION > +#ifdef CONFIG_JBD_DEBUG > +#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) > +#endif > +#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) > +#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long) > + > +/* > + * ioctl commands in 32 bit emulation > + */ > +#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS > +#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS > +#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) > +#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) > +#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) > +#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) > +#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) > +#ifdef CONFIG_JBD_DEBUG > +#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) > +#endif > +#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION > +#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION > + > + > +/* > + * Mount options > + */ > +struct ext3_mount_options { > + unsigned long s_mount_opt; > + uid_t s_resuid; > + gid_t s_resgid; > + unsigned long s_commit_interval; > +#ifdef CONFIG_QUOTA > + int s_jquota_fmt; > + char *s_qf_names[MAXQUOTAS]; > +#endif > +}; > + > +/* > + * Structure of an inode on the disk > + */ > +struct ext3_inode { > + __le16 i_mode; /* File mode */ > + __le16 i_uid; /* Low 16 bits of Owner Uid */ > + __le32 i_size; /* Size in bytes */ > + __le32 i_atime; /* Access time */ > + __le32 i_ctime; /* Creation time */ > + __le32 i_mtime; /* Modification time */ > + __le32 i_dtime; /* Deletion Time */ > + __le16 i_gid; /* Low 16 bits of Group Id */ > + __le16 i_links_count; /* Links count */ > + __le32 i_blocks; /* Blocks count */ > + __le32 i_flags; /* File flags */ > + union { > + struct { > + __u32 l_i_reserved1; > + } linux1; > + struct { > + __u32 h_i_translator; > + } hurd1; > + struct { > + __u32 m_i_reserved1; > + } masix1; > + } osd1; /* OS dependent 1 */ > + __le32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */ > + __le32 i_generation; /* File version (for NFS) */ > + __le32 i_file_acl; /* File ACL */ > + __le32 i_dir_acl; /* Directory ACL */ > + __le32 i_faddr; /* Fragment address */ > + union { > + struct { > + __u8 l_i_frag; /* Fragment number */ > + __u8 l_i_fsize; /* Fragment size */ > + __u16 i_pad1; > + __le16 l_i_uid_high; /* these 2 fields */ > + __le16 l_i_gid_high; /* were reserved2[0] */ > + __u32 l_i_reserved2; > + } linux2; > + struct { > + __u8 h_i_frag; /* Fragment number */ > + __u8 h_i_fsize; /* Fragment size */ > + __u16 h_i_mode_high; > + __u16 h_i_uid_high; > + __u16 h_i_gid_high; > + __u32 h_i_author; > + } hurd2; > + struct { > + __u8 m_i_frag; /* Fragment number */ > + __u8 m_i_fsize; /* Fragment size */ > + __u16 m_pad1; > + __u32 m_i_reserved2[2]; > + } masix2; > + } osd2; /* OS dependent 2 */ > + __le16 i_extra_isize; > + __le16 i_pad1; > +}; > + > +#define i_size_high i_dir_acl > + > +#define i_reserved1 osd1.linux1.l_i_reserved1 > +#define i_frag osd2.linux2.l_i_frag > +#define i_fsize osd2.linux2.l_i_fsize > +#define i_uid_low i_uid > +#define i_gid_low i_gid > +#define i_uid_high osd2.linux2.l_i_uid_high > +#define i_gid_high osd2.linux2.l_i_gid_high > +#define i_reserved2 osd2.linux2.l_i_reserved2 > + > +/* > + * File system states > + */ > +#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */ > +#define EXT3_ERROR_FS 0x0002 /* Errors detected */ > +#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */ > + > +/* > + * Misc. filesystem flags > + */ > +#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ > +#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ > +#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ > + > +/* > + * Mount flags > + */ > +#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */ > +/* EXT3_MOUNT_OLDALLOC was there */ > +#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */ > +#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */ > +#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ > +#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ > +#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ > +#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ > +#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ > +#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */ > +#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ > +#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ > +#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ > +#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ > +#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ > +#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ > +#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ > +#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ > +#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ > +#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ > +#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ > +#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ > +#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ > +#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write > + * error in ordered mode */ > + > +/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ > +#ifndef _LINUX_EXT2_FS_H > +#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt > +#define set_opt(o, opt) o |= EXT3_MOUNT_##opt > +#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ > + EXT3_MOUNT_##opt) > +#else > +#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD > +#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT > +#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS > +#endif > + > +#define ext3_set_bit __set_bit_le > +#define ext3_set_bit_atomic ext2_set_bit_atomic > +#define ext3_clear_bit __clear_bit_le > +#define ext3_clear_bit_atomic ext2_clear_bit_atomic > +#define ext3_test_bit test_bit_le > +#define ext3_find_next_zero_bit find_next_zero_bit_le > + > +/* > + * Maximal mount counts between two filesystem checks > + */ > +#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ > +#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */ > + > +/* > + * Behaviour when detecting errors > + */ > +#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */ > +#define EXT3_ERRORS_RO 2 /* Remount fs read-only */ > +#define EXT3_ERRORS_PANIC 3 /* Panic */ > +#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE > + > +/* > + * Structure of the super block > + */ > +struct ext3_super_block { > +/*00*/ __le32 s_inodes_count; /* Inodes count */ > + __le32 s_blocks_count; /* Blocks count */ > + __le32 s_r_blocks_count; /* Reserved blocks count */ > + __le32 s_free_blocks_count; /* Free blocks count */ > +/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ > + __le32 s_first_data_block; /* First Data Block */ > + __le32 s_log_block_size; /* Block size */ > + __le32 s_log_frag_size; /* Fragment size */ > +/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ > + __le32 s_frags_per_group; /* # Fragments per group */ > + __le32 s_inodes_per_group; /* # Inodes per group */ > + __le32 s_mtime; /* Mount time */ > +/*30*/ __le32 s_wtime; /* Write time */ > + __le16 s_mnt_count; /* Mount count */ > + __le16 s_max_mnt_count; /* Maximal mount count */ > + __le16 s_magic; /* Magic signature */ > + __le16 s_state; /* File system state */ > + __le16 s_errors; /* Behaviour when detecting errors */ > + __le16 s_minor_rev_level; /* minor revision level */ > +/*40*/ __le32 s_lastcheck; /* time of last check */ > + __le32 s_checkinterval; /* max. time between checks */ > + __le32 s_creator_os; /* OS */ > + __le32 s_rev_level; /* Revision level */ > +/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ > + __le16 s_def_resgid; /* Default gid for reserved blocks */ > + /* > + * These fields are for EXT3_DYNAMIC_REV superblocks only. > + * > + * Note: the difference between the compatible feature set and > + * the incompatible feature set is that if there is a bit set > + * in the incompatible feature set that the kernel doesn't > + * know about, it should refuse to mount the filesystem. > + * > + * e2fsck's requirements are more strict; if it doesn't know > + * about a feature in either the compatible or incompatible > + * feature set, it must abort and not try to meddle with > + * things it doesn't understand... > + */ > + __le32 s_first_ino; /* First non-reserved inode */ > + __le16 s_inode_size; /* size of inode structure */ > + __le16 s_block_group_nr; /* block group # of this superblock */ > + __le32 s_feature_compat; /* compatible feature set */ > +/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ > + __le32 s_feature_ro_compat; /* readonly-compatible feature set */ > +/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ > +/*78*/ char s_volume_name[16]; /* volume name */ > +/*88*/ char s_last_mounted[64]; /* directory where last mounted */ > +/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ > + /* > + * Performance hints. Directory preallocation should only > + * happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on. > + */ > + __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ > + __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ > + __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ > + /* > + * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. > + */ > +/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ > +/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ > + __le32 s_journal_dev; /* device number of journal file */ > + __le32 s_last_orphan; /* start of list of inodes to delete */ > + __le32 s_hash_seed[4]; /* HTREE hash seed */ > + __u8 s_def_hash_version; /* Default hash version to use */ > + __u8 s_reserved_char_pad; > + __u16 s_reserved_word_pad; > + __le32 s_default_mount_opts; > + __le32 s_first_meta_bg; /* First metablock block group */ > + __le32 s_mkfs_time; /* When the filesystem was created */ > + __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ > + /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ > +/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ > + __le32 s_r_blocks_count_hi; /* Reserved blocks count */ > + __le32 s_free_blocks_count_hi; /* Free blocks count */ > + __le16 s_min_extra_isize; /* All inodes have at least # bytes */ > + __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ > + __le32 s_flags; /* Miscellaneous flags */ > + __le16 s_raid_stride; /* RAID stride */ > + __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ > + __le64 s_mmp_block; /* Block for multi-mount protection */ > + __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ > + __u8 s_log_groups_per_flex; /* FLEX_BG group size */ > + __u8 s_reserved_char_pad2; > + __le16 s_reserved_pad; > + __u32 s_reserved[162]; /* Padding to the end of the block */ > +}; > + > +/* data type for block offset of block group */ > +typedef int ext3_grpblk_t; > + > +/* data type for filesystem-wide blocks number */ > +typedef unsigned long ext3_fsblk_t; > + > +#define E3FSBLK "%lu" > + > +struct ext3_reserve_window { > + ext3_fsblk_t _rsv_start; /* First byte reserved */ > + ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ > +}; > + > +struct ext3_reserve_window_node { > + struct rb_node rsv_node; > + __u32 rsv_goal_size; > + __u32 rsv_alloc_hit; > + struct ext3_reserve_window rsv_window; > +}; > + > +struct ext3_block_alloc_info { > + /* information about reservation window */ > + struct ext3_reserve_window_node rsv_window_node; > + /* > + * was i_next_alloc_block in ext3_inode_info > + * is the logical (file-relative) number of the > + * most-recently-allocated block in this file. > + * We use this for detecting linearly ascending allocation requests. > + */ > + __u32 last_alloc_logical_block; > + /* > + * Was i_next_alloc_goal in ext3_inode_info > + * is the *physical* companion to i_next_alloc_block. > + * it the physical block number of the block which was most-recentl > + * allocated to this file. This give us the goal (target) for the next > + * allocation when we detect linearly ascending requests. > + */ > + ext3_fsblk_t last_alloc_physical_block; > +}; > + > +#define rsv_start rsv_window._rsv_start > +#define rsv_end rsv_window._rsv_end > + > +/* > + * third extended file system inode data in memory > + */ > +struct ext3_inode_info { > + __le32 i_data[15]; /* unconverted */ > + __u32 i_flags; > +#ifdef EXT3_FRAGMENTS > + __u32 i_faddr; > + __u8 i_frag_no; > + __u8 i_frag_size; > +#endif > + ext3_fsblk_t i_file_acl; > + __u32 i_dir_acl; > + __u32 i_dtime; > + > + /* > + * i_block_group is the number of the block group which contains > + * this file's inode. Constant across the lifetime of the inode, > + * it is ued for making block allocation decisions - we try to > + * place a file's data blocks near its inode block, and new inodes > + * near to their parent directory's inode. > + */ > + __u32 i_block_group; > + unsigned long i_state_flags; /* Dynamic state flags for ext3 */ > + > + /* block reservation info */ > + struct ext3_block_alloc_info *i_block_alloc_info; > + > + __u32 i_dir_start_lookup; > +#ifdef CONFIG_EXT3_FS_XATTR > + /* > + * Extended attributes can be read independently of the main file > + * data. Taking i_mutex even when reading would cause contention > + * between readers of EAs and writers of regular file data, so > + * instead we synchronize on xattr_sem when reading or changing > + * EAs. > + */ > + struct rw_semaphore xattr_sem; > +#endif > + > + struct list_head i_orphan; /* unlinked but open inodes */ > + > + /* > + * i_disksize keeps track of what the inode size is ON DISK, not > + * in memory. During truncate, i_size is set to the new size by > + * the VFS prior to calling ext3_truncate(), but the filesystem won't > + * set i_disksize to 0 until the truncate is actually under way. > + * > + * The intent is that i_disksize always represents the blocks which > + * are used by this file. This allows recovery to restart truncate > + * on orphans if we crash during truncate. We actually write i_disksize > + * into the on-disk inode when writing inodes out, instead of i_size. > + * > + * The only time when i_disksize and i_size may be different is when > + * a truncate is in progress. The only things which change i_disksize > + * are ext3_get_block (growth) and ext3_truncate (shrinkth). > + */ > + loff_t i_disksize; > + > + /* on-disk additional length */ > + __u16 i_extra_isize; > + > + /* > + * truncate_mutex is for serialising ext3_truncate() against > + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's > + * data tree are chopped off during truncate. We can't do that in > + * ext3 because whenever we perform intermediate commits during > + * truncate, the inode and all the metadata blocks *must* be in a > + * consistent state which allows truncation of the orphans to restart > + * during recovery. Hence we must fix the get_block-vs-truncate race > + * by other means, so we have truncate_mutex. > + */ > + struct mutex truncate_mutex; > + > + /* > + * Transactions that contain inode's metadata needed to complete > + * fsync and fdatasync, respectively. > + */ > + atomic_t i_sync_tid; > + atomic_t i_datasync_tid; > + > + struct inode vfs_inode; > +}; > + > +/* > + * third extended-fs super-block data in memory > + */ > +struct ext3_sb_info { > + unsigned long s_frag_size; /* Size of a fragment in bytes */ > + unsigned long s_frags_per_block;/* Number of fragments per block */ > + unsigned long s_inodes_per_block;/* Number of inodes per block */ > + unsigned long s_frags_per_group;/* Number of fragments in a group */ > + unsigned long s_blocks_per_group;/* Number of blocks in a group */ > + unsigned long s_inodes_per_group;/* Number of inodes in a group */ > + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ > + unsigned long s_gdb_count; /* Number of group descriptor blocks */ > + unsigned long s_desc_per_block; /* Number of group descriptors per block */ > + unsigned long s_groups_count; /* Number of groups in the fs */ > + unsigned long s_overhead_last; /* Last calculated overhead */ > + unsigned long s_blocks_last; /* Last seen block count */ > + struct buffer_head * s_sbh; /* Buffer containing the super block */ > + struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ > + struct buffer_head ** s_group_desc; > + unsigned long s_mount_opt; > + ext3_fsblk_t s_sb_block; > + uid_t s_resuid; > + gid_t s_resgid; > + unsigned short s_mount_state; > + unsigned short s_pad; > + int s_addr_per_block_bits; > + int s_desc_per_block_bits; > + int s_inode_size; > + int s_first_ino; > + spinlock_t s_next_gen_lock; > + u32 s_next_generation; > + u32 s_hash_seed[4]; > + int s_def_hash_version; > + int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ > + struct percpu_counter s_freeblocks_counter; > + struct percpu_counter s_freeinodes_counter; > + struct percpu_counter s_dirs_counter; > + struct blockgroup_lock *s_blockgroup_lock; > + > + /* root of the per fs reservation window tree */ > + spinlock_t s_rsv_window_lock; > + struct rb_root s_rsv_window_root; > + struct ext3_reserve_window_node s_rsv_window_head; > + > + /* Journaling */ > + struct inode * s_journal_inode; > + struct journal_s * s_journal; > + struct list_head s_orphan; > + struct mutex s_orphan_lock; > + struct mutex s_resize_lock; > + unsigned long s_commit_interval; > + struct block_device *journal_bdev; > +#ifdef CONFIG_QUOTA > + char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ > + int s_jquota_fmt; /* Format of quota to use */ > +#endif > +}; > + > +static inline spinlock_t * > +sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) > +{ > + return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); > +} > + > +static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) > +{ > + return sb->s_fs_info; > +} > +static inline struct ext3_inode_info *EXT3_I(struct inode *inode) > +{ > + return container_of(inode, struct ext3_inode_info, vfs_inode); > +} > + > +static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) > +{ > + return ino == EXT3_ROOT_INO || > + ino == EXT3_JOURNAL_INO || > + ino == EXT3_RESIZE_INO || > + (ino >= EXT3_FIRST_INO(sb) && > + ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); > +} > + > +/* > + * Inode dynamic state flags > + */ > +enum { > + EXT3_STATE_JDATA, /* journaled data exists */ > + EXT3_STATE_NEW, /* inode is newly created */ > + EXT3_STATE_XATTR, /* has in-inode xattrs */ > + EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ > +}; > + > +static inline int ext3_test_inode_state(struct inode *inode, int bit) > +{ > + return test_bit(bit, &EXT3_I(inode)->i_state_flags); > +} > + > +static inline void ext3_set_inode_state(struct inode *inode, int bit) > +{ > + set_bit(bit, &EXT3_I(inode)->i_state_flags); > +} > + > +static inline void ext3_clear_inode_state(struct inode *inode, int bit) > +{ > + clear_bit(bit, &EXT3_I(inode)->i_state_flags); > +} > + > +#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime > + > +/* > + * Codes for operating systems > + */ > +#define EXT3_OS_LINUX 0 > +#define EXT3_OS_HURD 1 > +#define EXT3_OS_MASIX 2 > +#define EXT3_OS_FREEBSD 3 > +#define EXT3_OS_LITES 4 > + > +/* > + * Revision levels > + */ > +#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */ > +#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ > + > +#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV > +#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV > + > +#define EXT3_GOOD_OLD_INODE_SIZE 128 > + > +/* > + * Feature set definitions > + */ > + > +#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \ > + ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) > +#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \ > + ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) > +#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \ > + ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) > +#define EXT3_SET_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) > +#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) > +#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) > +#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) > +#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) > +#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) > + > +#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001 > +#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002 > +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 > +#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008 > +#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010 > +#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020 > + > +#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 > +#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 > +#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 > + > +#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001 > +#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 > +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ > +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ > +#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 > + > +#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR > +#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ > + EXT3_FEATURE_INCOMPAT_RECOVER| \ > + EXT3_FEATURE_INCOMPAT_META_BG) > +#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ > + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ > + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) > + > +/* > + * Default values for user and/or group using reserved blocks > + */ > +#define EXT3_DEF_RESUID 0 > +#define EXT3_DEF_RESGID 0 > + > +/* > + * Default mount options > + */ > +#define EXT3_DEFM_DEBUG 0x0001 > +#define EXT3_DEFM_BSDGROUPS 0x0002 > +#define EXT3_DEFM_XATTR_USER 0x0004 > +#define EXT3_DEFM_ACL 0x0008 > +#define EXT3_DEFM_UID16 0x0010 > +#define EXT3_DEFM_JMODE 0x0060 > +#define EXT3_DEFM_JMODE_DATA 0x0020 > +#define EXT3_DEFM_JMODE_ORDERED 0x0040 > +#define EXT3_DEFM_JMODE_WBACK 0x0060 > + > +/* > + * Structure of a directory entry > + */ > +#define EXT3_NAME_LEN 255 > + > +struct ext3_dir_entry { > + __le32 inode; /* Inode number */ > + __le16 rec_len; /* Directory entry length */ > + __le16 name_len; /* Name length */ > + char name[EXT3_NAME_LEN]; /* File name */ > +}; > + > +/* > + * The new version of the directory entry. Since EXT3 structures are > + * stored in intel byte order, and the name_len field could never be > + * bigger than 255 chars, it's safe to reclaim the extra byte for the > + * file_type field. > + */ > +struct ext3_dir_entry_2 { > + __le32 inode; /* Inode number */ > + __le16 rec_len; /* Directory entry length */ > + __u8 name_len; /* Name length */ > + __u8 file_type; > + char name[EXT3_NAME_LEN]; /* File name */ > +}; > + > +/* > + * Ext3 directory file types. Only the low 3 bits are used. The > + * other bits are reserved for now. > + */ > +#define EXT3_FT_UNKNOWN 0 > +#define EXT3_FT_REG_FILE 1 > +#define EXT3_FT_DIR 2 > +#define EXT3_FT_CHRDEV 3 > +#define EXT3_FT_BLKDEV 4 > +#define EXT3_FT_FIFO 5 > +#define EXT3_FT_SOCK 6 > +#define EXT3_FT_SYMLINK 7 > + > +#define EXT3_FT_MAX 8 > + > +/* > + * EXT3_DIR_PAD defines the directory entries boundaries > + * > + * NOTE: It must be a multiple of 4 > + */ > +#define EXT3_DIR_PAD 4 > +#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) > +#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ > + ~EXT3_DIR_ROUND) > +#define EXT3_MAX_REC_LEN ((1<<16)-1) > + > +/* > + * Tests against MAX_REC_LEN etc were put in place for 64k block > + * sizes; if that is not possible on this arch, we can skip > + * those tests and speed things up. > + */ > +static inline unsigned ext3_rec_len_from_disk(__le16 dlen) > +{ > + unsigned len = le16_to_cpu(dlen); > + > +#if (PAGE_CACHE_SIZE >= 65536) > + if (len == EXT3_MAX_REC_LEN) > + return 1 << 16; > +#endif > + return len; > +} > + > +static inline __le16 ext3_rec_len_to_disk(unsigned len) > +{ > +#if (PAGE_CACHE_SIZE >= 65536) > + if (len == (1 << 16)) > + return cpu_to_le16(EXT3_MAX_REC_LEN); > + else if (len > (1 << 16)) > + BUG(); > +#endif > + return cpu_to_le16(len); > +} > + > +/* > + * Hash Tree Directory indexing > + * (c) Daniel Phillips, 2001 > + */ > + > +#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ > + EXT3_FEATURE_COMPAT_DIR_INDEX) && \ > + (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) > +#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) > +#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) > + > +/* Legal values for the dx_root hash_version field: */ > + > +#define DX_HASH_LEGACY 0 > +#define DX_HASH_HALF_MD4 1 > +#define DX_HASH_TEA 2 > +#define DX_HASH_LEGACY_UNSIGNED 3 > +#define DX_HASH_HALF_MD4_UNSIGNED 4 > +#define DX_HASH_TEA_UNSIGNED 5 > + > +/* hash info structure used by the directory hash */ > +struct dx_hash_info > +{ > + u32 hash; > + u32 minor_hash; > + int hash_version; > + u32 *seed; > +}; > + > +#define EXT3_HTREE_EOF 0x7fffffff > + > +/* > + * Control parameters used by ext3_htree_next_block > + */ > +#define HASH_NB_ALWAYS 1 > + > + > +/* > + * Describe an inode's exact location on disk and in memory > + */ > +struct ext3_iloc > +{ > + struct buffer_head *bh; > + unsigned long offset; > + unsigned long block_group; > +}; > + > +static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc) > +{ > + return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset); > +} > + > +/* > + * This structure is stuffed into the struct file's private_data field > + * for directories. It is where we put information so that we can do > + * readdir operations in hash tree order. > + */ > +struct dir_private_info { > + struct rb_root root; > + struct rb_node *curr_node; > + struct fname *extra_fname; > + loff_t last_pos; > + __u32 curr_hash; > + __u32 curr_minor_hash; > + __u32 next_hash; > +}; > + > +/* calculate the first block number of the group */ > +static inline ext3_fsblk_t > +ext3_group_first_block_no(struct super_block *sb, unsigned long group_no) > +{ > + return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) + > + le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); > +} > + > +/* > + * Special error return code only used by dx_probe() and its callers. > + */ > +#define ERR_BAD_DX_DIR -75000 > + > +/* > + * Function prototypes > + */ > + > +/* > + * Ok, these declarations are also in but none of the > + * ext3 source programs needs to include it so they are duplicated here. > + */ > +# define NORET_TYPE /**/ > +# define ATTRIB_NORET __attribute__((noreturn)) > +# define NORET_AND noreturn, > + > +/* balloc.c */ > +extern int ext3_bg_has_super(struct super_block *sb, int group); > +extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); > +extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode, > + ext3_fsblk_t goal, int *errp); > +extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode, > + ext3_fsblk_t goal, unsigned long *count, int *errp); > +extern void ext3_free_blocks (handle_t *handle, struct inode *inode, > + ext3_fsblk_t block, unsigned long count); > +extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb, > + ext3_fsblk_t block, unsigned long count, > + unsigned long *pdquot_freed_blocks); > +extern ext3_fsblk_t ext3_count_free_blocks (struct super_block *); > +extern void ext3_check_blocks_bitmap (struct super_block *); > +extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, > + unsigned int block_group, > + struct buffer_head ** bh); > +extern int ext3_should_retry_alloc(struct super_block *sb, int *retries); > +extern void ext3_init_block_alloc_info(struct inode *); > +extern void ext3_rsv_window_add(struct super_block *sb, struct ext3_reserve_window_node *rsv); > +extern int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range); > + > +/* dir.c */ > +extern int ext3_check_dir_entry(const char *, struct inode *, > + struct ext3_dir_entry_2 *, > + struct buffer_head *, unsigned long); > +extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, > + __u32 minor_hash, > + struct ext3_dir_entry_2 *dirent); > +extern void ext3_htree_free_dir_info(struct dir_private_info *p); > + > +/* fsync.c */ > +extern int ext3_sync_file(struct file *, loff_t, loff_t, int); > + > +/* hash.c */ > +extern int ext3fs_dirhash(const char *name, int len, struct > + dx_hash_info *hinfo); > + > +/* ialloc.c */ > +extern struct inode * ext3_new_inode (handle_t *, struct inode *, > + const struct qstr *, umode_t); > +extern void ext3_free_inode (handle_t *, struct inode *); > +extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); > +extern unsigned long ext3_count_free_inodes (struct super_block *); > +extern unsigned long ext3_count_dirs (struct super_block *); > +extern void ext3_check_inodes_bitmap (struct super_block *); > +extern unsigned long ext3_count_free (struct buffer_head *, unsigned); > + > + > +/* inode.c */ > +int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, > + struct buffer_head *bh, ext3_fsblk_t blocknr); > +struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); > +struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); > +int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, > + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, > + int create); > + > +extern struct inode *ext3_iget(struct super_block *, unsigned long); > +extern int ext3_write_inode (struct inode *, struct writeback_control *); > +extern int ext3_setattr (struct dentry *, struct iattr *); > +extern void ext3_evict_inode (struct inode *); > +extern int ext3_sync_inode (handle_t *, struct inode *); > +extern void ext3_discard_reservation (struct inode *); > +extern void ext3_dirty_inode(struct inode *, int); > +extern int ext3_change_inode_journal_flag(struct inode *, int); > +extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); > +extern int ext3_can_truncate(struct inode *inode); > +extern void ext3_truncate(struct inode *inode); > +extern void ext3_set_inode_flags(struct inode *); > +extern void ext3_get_inode_flags(struct ext3_inode_info *); > +extern void ext3_set_aops(struct inode *inode); > +extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, > + u64 start, u64 len); > + > +/* ioctl.c */ > +extern long ext3_ioctl(struct file *, unsigned int, unsigned long); > +extern long ext3_compat_ioctl(struct file *, unsigned int, unsigned long); > + > +/* namei.c */ > +extern int ext3_orphan_add(handle_t *, struct inode *); > +extern int ext3_orphan_del(handle_t *, struct inode *); > +extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, > + __u32 start_minor_hash, __u32 *next_hash); > + > +/* resize.c */ > +extern int ext3_group_add(struct super_block *sb, > + struct ext3_new_group_data *input); > +extern int ext3_group_extend(struct super_block *sb, > + struct ext3_super_block *es, > + ext3_fsblk_t n_blocks_count); > + > +/* super.c */ > +extern __printf(3, 4) > +void ext3_error(struct super_block *, const char *, const char *, ...); > +extern void __ext3_std_error (struct super_block *, const char *, int); > +extern __printf(3, 4) > +void ext3_abort(struct super_block *, const char *, const char *, ...); > +extern __printf(3, 4) > +void ext3_warning(struct super_block *, const char *, const char *, ...); > +extern __printf(3, 4) > +void ext3_msg(struct super_block *, const char *, const char *, ...); > +extern void ext3_update_dynamic_rev (struct super_block *sb); > + > +#define ext3_std_error(sb, errno) \ > +do { \ > + if ((errno)) \ > + __ext3_std_error((sb), __func__, (errno)); \ > +} while (0) > + > +/* > + * Inodes and files operations > + */ > + > +/* dir.c */ > +extern const struct file_operations ext3_dir_operations; > + > +/* file.c */ > +extern const struct inode_operations ext3_file_inode_operations; > +extern const struct file_operations ext3_file_operations; > + > +/* namei.c */ > +extern const struct inode_operations ext3_dir_inode_operations; > +extern const struct inode_operations ext3_special_inode_operations; > + > +/* symlink.c */ > +extern const struct inode_operations ext3_symlink_inode_operations; > +extern const struct inode_operations ext3_fast_symlink_inode_operations; > + > +#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) > + > +/* Define the number of blocks we need to account to a transaction to > + * modify one block of data. > + * > + * We may have to touch one inode, one bitmap buffer, up to three > + * indirection blocks, the group and superblock summaries, and the data > + * block to complete the transaction. */ > + > +#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U > + > +/* Extended attribute operations touch at most two data buffers, > + * two bitmap buffers, and two group summaries, in addition to the inode > + * and the superblock, which are already accounted for. */ > + > +#define EXT3_XATTR_TRANS_BLOCKS 6U > + > +/* Define the minimum size for a transaction which modifies data. This > + * needs to take into account the fact that we may end up modifying two > + * quota files too (one for the group, one for the user quota). The > + * superblock only gets updated once, of course, so don't bother > + * counting that again for the quota updates. */ > + > +#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ > + EXT3_XATTR_TRANS_BLOCKS - 2 + \ > + EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) > + > +/* Delete operations potentially hit one directory's namespace plus an > + * entire inode, plus arbitrary amounts of bitmap/indirection data. Be > + * generous. We can grow the delete transaction later if necessary. */ > + > +#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) > + > +/* Define an arbitrary limit for the amount of data we will anticipate > + * writing to any given transaction. For unbounded transactions such as > + * write(2) and truncate(2) we can write more than this, but we always > + * start off at the maximum transaction size and grow the transaction > + * optimistically as we go. */ > + > +#define EXT3_MAX_TRANS_DATA 64U > + > +/* We break up a large truncate or write transaction once the handle's > + * buffer credits gets this low, we need either to extend the > + * transaction or to start a new one. Reserve enough space here for > + * inode, bitmap, superblock, group and indirection updates for at least > + * one block, plus two quota updates. Quota allocations are not > + * needed. */ > + > +#define EXT3_RESERVE_TRANS_BLOCKS 12U > + > +#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 > + > +#ifdef CONFIG_QUOTA > +/* Amount of blocks needed for quota update - we know that the structure was > + * allocated so we need to update only inode+data */ > +#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) > +/* Amount of blocks needed for quota insert/delete - we do some block writes > + * but inode, sb and group updates are done only once */ > +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ > + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) > +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ > + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) > +#else > +#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 > +#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 > +#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 > +#endif > +#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) > +#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) > +#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) > + > +int > +ext3_mark_iloc_dirty(handle_t *handle, > + struct inode *inode, > + struct ext3_iloc *iloc); > + > +/* > + * On success, We end up with an outstanding reference count against > + * iloc->bh. This _must_ be cleaned up later. > + */ > + > +int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, > + struct ext3_iloc *iloc); > + > +int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); > + > +/* > + * Wrapper functions with which ext3 calls into JBD. The intent here is > + * to allow these to be turned into appropriate stubs so ext3 can control > + * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't > + * been done yet. > + */ > + > +static inline void ext3_journal_release_buffer(handle_t *handle, > + struct buffer_head *bh) > +{ > + journal_release_buffer(handle, bh); > +} > + > +void ext3_journal_abort_handle(const char *caller, const char *err_fn, > + struct buffer_head *bh, handle_t *handle, int err); > + > +int __ext3_journal_get_undo_access(const char *where, handle_t *handle, > + struct buffer_head *bh); > + > +int __ext3_journal_get_write_access(const char *where, handle_t *handle, > + struct buffer_head *bh); > + > +int __ext3_journal_forget(const char *where, handle_t *handle, > + struct buffer_head *bh); > + > +int __ext3_journal_revoke(const char *where, handle_t *handle, > + unsigned long blocknr, struct buffer_head *bh); > + > +int __ext3_journal_get_create_access(const char *where, > + handle_t *handle, struct buffer_head *bh); > + > +int __ext3_journal_dirty_metadata(const char *where, > + handle_t *handle, struct buffer_head *bh); > + > +#define ext3_journal_get_undo_access(handle, bh) \ > + __ext3_journal_get_undo_access(__func__, (handle), (bh)) > +#define ext3_journal_get_write_access(handle, bh) \ > + __ext3_journal_get_write_access(__func__, (handle), (bh)) > +#define ext3_journal_revoke(handle, blocknr, bh) \ > + __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) > +#define ext3_journal_get_create_access(handle, bh) \ > + __ext3_journal_get_create_access(__func__, (handle), (bh)) > +#define ext3_journal_dirty_metadata(handle, bh) \ > + __ext3_journal_dirty_metadata(__func__, (handle), (bh)) > +#define ext3_journal_forget(handle, bh) \ > + __ext3_journal_forget(__func__, (handle), (bh)) > + > +int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); > + > +handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); > +int __ext3_journal_stop(const char *where, handle_t *handle); > + > +static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) > +{ > + return ext3_journal_start_sb(inode->i_sb, nblocks); > +} > + > +#define ext3_journal_stop(handle) \ > + __ext3_journal_stop(__func__, (handle)) > + > +static inline handle_t *ext3_journal_current_handle(void) > +{ > + return journal_current_handle(); > +} > + > +static inline int ext3_journal_extend(handle_t *handle, int nblocks) > +{ > + return journal_extend(handle, nblocks); > +} > + > +static inline int ext3_journal_restart(handle_t *handle, int nblocks) > +{ > + return journal_restart(handle, nblocks); > +} > + > +static inline int ext3_journal_blocks_per_page(struct inode *inode) > +{ > + return journal_blocks_per_page(inode); > +} > + > +static inline int ext3_journal_force_commit(journal_t *journal) > +{ > + return journal_force_commit(journal); > +} > + > +/* super.c */ > +int ext3_force_commit(struct super_block *sb); > + > +static inline int ext3_should_journal_data(struct inode *inode) > +{ > + if (!S_ISREG(inode->i_mode)) > + return 1; > + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) > + return 1; > + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > + return 1; > + return 0; > +} > + > +static inline int ext3_should_order_data(struct inode *inode) > +{ > + if (!S_ISREG(inode->i_mode)) > + return 0; > + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > + return 0; > + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) > + return 1; > + return 0; > +} > + > +static inline int ext3_should_writeback_data(struct inode *inode) > +{ > + if (!S_ISREG(inode->i_mode)) > + return 0; > + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > + return 0; > + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) > + return 1; > + return 0; > +} > + > +#include > + > diff --git a/instrumentation/events/mainline/gpio.h b/instrumentation/events/mainline/gpio.h > new file mode 100644 > index 0000000..927a8ad > --- /dev/null > +++ b/instrumentation/events/mainline/gpio.h > @@ -0,0 +1,56 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM gpio > + > +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_GPIO_H > + > +#include > + > +TRACE_EVENT(gpio_direction, > + > + TP_PROTO(unsigned gpio, int in, int err), > + > + TP_ARGS(gpio, in, err), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, in) > + __field(int, err) > + ), > + > + TP_fast_assign( > + __entry->gpio = gpio; > + __entry->in = in; > + __entry->err = err; > + ), > + > + TP_printk("%u %3s (%d)", __entry->gpio, > + __entry->in ? "in" : "out", __entry->err) > +); > + > +TRACE_EVENT(gpio_value, > + > + TP_PROTO(unsigned gpio, int get, int value), > + > + TP_ARGS(gpio, get, value), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, get) > + __field(int, value) > + ), > + > + TP_fast_assign( > + __entry->gpio = gpio; > + __entry->get = get; > + __entry->value = value; > + ), > + > + TP_printk("%u %3s %d", __entry->gpio, > + __entry->get ? "get" : "set", __entry->value) > +); > + > +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/jbd.h b/instrumentation/events/mainline/jbd.h > new file mode 100644 > index 0000000..aff64d8 > --- /dev/null > +++ b/instrumentation/events/mainline/jbd.h > @@ -0,0 +1,203 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd > + > +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD_H > + > +#include > +#include > + > +TRACE_EVENT(jbd_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->result = result; > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->result) > +); > + > +DECLARE_EVENT_CLASS(jbd_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +TRACE_EVENT(jbd_drop_transaction, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +TRACE_EVENT(jbd_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + __entry->head = journal->j_tail_sequence; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +); > + > +TRACE_EVENT(jbd_do_submit_data, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +TRACE_EVENT(jbd_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->tail_sequence = journal->j_tail_sequence; > + __entry->first_tid = first_tid; > + __entry->block_nr = block_nr; > + __entry->freed = freed; > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +); > + > +TRACE_EVENT(jbd_update_superblock_end, > + TP_PROTO(journal_t *journal, int wait), > + > + TP_ARGS(journal, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->wait = wait; > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +); > + > +#endif /* _TRACE_JBD_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/jbd2.h b/instrumentation/events/mainline/jbd2.h > new file mode 100644 > index 0000000..7596441 > --- /dev/null > +++ b/instrumentation/events/mainline/jbd2.h > @@ -0,0 +1,235 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd2 > + > +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD2_H > + > +#include > +#include > + > +struct transaction_chp_stats_s; > +struct transaction_run_stats_s; > + > +TRACE_EVENT(jbd2_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->result = result; > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) > +); > + > +DECLARE_EVENT_CLASS(jbd2_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +TRACE_EVENT(jbd2_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + __entry->head = journal->j_tail_sequence; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +); > + > +TRACE_EVENT(jbd2_submit_inode_data, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +); > + > +TRACE_EVENT(jbd2_run_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_run_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, wait ) > + __field( unsigned long, running ) > + __field( unsigned long, locked ) > + __field( unsigned long, flushing ) > + __field( unsigned long, logging ) > + __field( __u32, handle_count ) > + __field( __u32, blocks ) > + __field( __u32, blocks_logged ) > + ), > + > + TP_fast_assign( > + __entry->dev = dev; > + __entry->tid = tid; > + __entry->wait = stats->rs_wait; > + __entry->running = stats->rs_running; > + __entry->locked = stats->rs_locked; > + __entry->flushing = stats->rs_flushing; > + __entry->logging = stats->rs_logging; > + __entry->handle_count = stats->rs_handle_count; > + __entry->blocks = stats->rs_blocks; > + __entry->blocks_logged = stats->rs_blocks_logged; > + ), > + > + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " > + "logging %u handle_count %u blocks %u blocks_logged %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->wait), > + jiffies_to_msecs(__entry->running), > + jiffies_to_msecs(__entry->locked), > + jiffies_to_msecs(__entry->flushing), > + jiffies_to_msecs(__entry->logging), > + __entry->handle_count, __entry->blocks, > + __entry->blocks_logged) > +); > + > +TRACE_EVENT(jbd2_checkpoint_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_chp_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, chp_time ) > + __field( __u32, forced_to_close ) > + __field( __u32, written ) > + __field( __u32, dropped ) > + ), > + > + TP_fast_assign( > + __entry->dev = dev; > + __entry->tid = tid; > + __entry->chp_time = stats->cs_chp_time; > + __entry->forced_to_close= stats->cs_forced_to_close; > + __entry->written = stats->cs_written; > + __entry->dropped = stats->cs_dropped; > + ), > + > + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " > + "written %u dropped %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->chp_time), > + __entry->forced_to_close, __entry->written, __entry->dropped) > +); > + > +TRACE_EVENT(jbd2_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->tail_sequence = journal->j_tail_sequence; > + __entry->first_tid = first_tid; > + __entry->block_nr = block_nr; > + __entry->freed = freed; > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +); > + > +#endif /* _TRACE_JBD2_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/kmem.h b/instrumentation/events/mainline/kmem.h > new file mode 100644 > index 0000000..a9c87ad > --- /dev/null > +++ b/instrumentation/events/mainline/kmem.h > @@ -0,0 +1,308 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM kmem > + > +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_KMEM_H > + > +#include > +#include > +#include "gfpflags.h" > + > +DECLARE_EVENT_CLASS(kmem_alloc, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags)) > +); > + > +DEFINE_EVENT(kmem_alloc, kmalloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +); > + > +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +); > + > +DECLARE_EVENT_CLASS(kmem_alloc_node, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags, > + int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + __field( int, node ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + __entry->node = node; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags), > + __entry->node) > +); > + > +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +); > + > +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +); > + > +DECLARE_EVENT_CLASS(kmem_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + ), > + > + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > +); > + > +DEFINE_EVENT(kmem_free, kfree, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +); > + > +DEFINE_EVENT(kmem_free, kmem_cache_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +); > + > +TRACE_EVENT(mm_page_free_direct, > + > + TP_PROTO(struct page *page, unsigned int order), > + > + TP_ARGS(page, order), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->order = order; > + ), > + > + TP_printk("page=%p pfn=%lu order=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order) > +); > + > +TRACE_EVENT(mm_pagevec_free, > + > + TP_PROTO(struct page *page, int cold), > + > + TP_ARGS(page, cold), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, cold ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->cold = cold; > + ), > + > + TP_printk("page=%p pfn=%lu order=0 cold=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->cold) > +); > + > +TRACE_EVENT(mm_page_alloc, > + > + TP_PROTO(struct page *page, unsigned int order, > + gfp_t gfp_flags, int migratetype), > + > + TP_ARGS(page, order, gfp_flags, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( gfp_t, gfp_flags ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->order = order; > + __entry->gfp_flags = gfp_flags; > + __entry->migratetype = migratetype; > + ), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + show_gfp_flags(__entry->gfp_flags)) > +); > + > +DECLARE_EVENT_CLASS(mm_page, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->order = order; > + __entry->migratetype = migratetype; > + ), > + > + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + __entry->order == 0) > +); > + > +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype) > +); > + > +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", > + __entry->page, page_to_pfn(__entry->page), > + __entry->order, __entry->migratetype) > +); > + > +TRACE_EVENT(mm_page_alloc_extfrag, > + > + TP_PROTO(struct page *page, > + int alloc_order, int fallback_order, > + int alloc_migratetype, int fallback_migratetype), > + > + TP_ARGS(page, > + alloc_order, fallback_order, > + alloc_migratetype, fallback_migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, alloc_order ) > + __field( int, fallback_order ) > + __field( int, alloc_migratetype ) > + __field( int, fallback_migratetype ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->alloc_order = alloc_order; > + __entry->fallback_order = fallback_order; > + __entry->alloc_migratetype = alloc_migratetype; > + __entry->fallback_migratetype = fallback_migratetype; > + ), > + > + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->alloc_order, > + __entry->fallback_order, > + pageblock_order, > + __entry->alloc_migratetype, > + __entry->fallback_migratetype, > + __entry->fallback_order < pageblock_order, > + __entry->alloc_migratetype == __entry->fallback_migratetype) > +); > + > +#endif /* _TRACE_KMEM_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/lock.h b/instrumentation/events/mainline/lock.h > new file mode 100644 > index 0000000..2821b86 > --- /dev/null > +++ b/instrumentation/events/mainline/lock.h > @@ -0,0 +1,86 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM lock > + > +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_LOCK_H > + > +#include > +#include > + > +#ifdef CONFIG_LOCKDEP > + > +TRACE_EVENT(lock_acquire, > + > + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, > + int trylock, int read, int check, > + struct lockdep_map *next_lock, unsigned long ip), > + > + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), > + > + TP_STRUCT__entry( > + __field(unsigned int, flags) > + __string(name, lock->name) > + __field(void *, lockdep_addr) > + ), > + > + TP_fast_assign( > + __entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0); > + __assign_str(name, lock->name); > + __entry->lockdep_addr = lock; > + ), > + > + TP_printk("%p %s%s%s", __entry->lockdep_addr, > + (__entry->flags & 1) ? "try " : "", > + (__entry->flags & 2) ? "read " : "", > + __get_str(name)) > +); > + > +DECLARE_EVENT_CLASS(lock, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip), > + > + TP_STRUCT__entry( > + __string( name, lock->name ) > + __field( void *, lockdep_addr ) > + ), > + > + TP_fast_assign( > + __assign_str(name, lock->name); > + __entry->lockdep_addr = lock; > + ), > + > + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) > +); > + > +DEFINE_EVENT(lock, lock_release, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +); > + > +#ifdef CONFIG_LOCK_STAT > + > +DEFINE_EVENT(lock, lock_contended, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +); > + > +DEFINE_EVENT(lock, lock_acquired, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +); > + > +#endif > +#endif > + > +#endif /* _TRACE_LOCK_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/module.h b/instrumentation/events/mainline/module.h > new file mode 100644 > index 0000000..21a546d > --- /dev/null > +++ b/instrumentation/events/mainline/module.h > @@ -0,0 +1,131 @@ > +/* > + * Because linux/module.h has tracepoints in the header, and ftrace.h > + * eventually includes this file, define_trace.h includes linux/module.h > + * But we do not want the module.h to override the TRACE_SYSTEM macro > + * variable that define_trace.h is processing, so we only set it > + * when module events are being processed, which would happen when > + * CREATE_TRACE_POINTS is defined. > + */ > +#ifdef CREATE_TRACE_POINTS > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM module > +#endif > + > +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_MODULE_H > + > +#include > + > +#ifdef CONFIG_MODULES > + > +struct module; > + > +#define show_module_flags(flags) __print_flags(flags, "", \ > + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ > + { (1UL << TAINT_FORCED_MODULE), "F" }, \ > + { (1UL << TAINT_CRAP), "C" }) > + > +TRACE_EVENT(module_load, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __field( unsigned int, taints ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + __entry->taints = mod->taints; > + __assign_str(name, mod->name); > + ), > + > + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) > +); > + > +TRACE_EVENT(module_free, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, mod->name); > + ), > + > + TP_printk("%s", __get_str(name)) > +); > + > +#ifdef CONFIG_MODULE_UNLOAD > +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ > + > +DECLARE_EVENT_CLASS(module_refcnt, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( int, refcnt ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + __entry->ip = ip; > + __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs); > + __assign_str(name, mod->name); > + ), > + > + TP_printk("%s call_site=%pf refcnt=%d", > + __get_str(name), (void *)__entry->ip, __entry->refcnt) > +); > + > +DEFINE_EVENT(module_refcnt, module_get, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +); > + > +DEFINE_EVENT(module_refcnt, module_put, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +); > +#endif /* CONFIG_MODULE_UNLOAD */ > + > +TRACE_EVENT(module_request, > + > + TP_PROTO(char *name, bool wait, unsigned long ip), > + > + TP_ARGS(name, wait, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( bool, wait ) > + __string( name, name ) > + ), > + > + TP_fast_assign( > + __entry->ip = ip; > + __entry->wait = wait; > + __assign_str(name, name); > + ), > + > + TP_printk("%s wait=%d call_site=%pf", > + __get_str(name), (int)__entry->wait, (void *)__entry->ip) > +); > + > +#endif /* CONFIG_MODULES */ > + > +#endif /* _TRACE_MODULE_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/napi.h b/instrumentation/events/mainline/napi.h > new file mode 100644 > index 0000000..8fe1e93 > --- /dev/null > +++ b/instrumentation/events/mainline/napi.h > @@ -0,0 +1,38 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM napi > + > +#if !defined(_TRACE_NAPI_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NAPI_H_ > + > +#include > +#include > +#include > + > +#define NO_DEV "(no_device)" > + > +TRACE_EVENT(napi_poll, > + > + TP_PROTO(struct napi_struct *napi), > + > + TP_ARGS(napi), > + > + TP_STRUCT__entry( > + __field( struct napi_struct *, napi) > + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) > + ), > + > + TP_fast_assign( > + __entry->napi = napi; > + __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV); > + ), > + > + TP_printk("napi poll on napi struct %p for device %s", > + __entry->napi, __get_str(dev_name)) > +); > + > +#undef NO_DEV > + > +#endif /* _TRACE_NAPI_H_ */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/net.h b/instrumentation/events/mainline/net.h > new file mode 100644 > index 0000000..f99645d > --- /dev/null > +++ b/instrumentation/events/mainline/net.h > @@ -0,0 +1,84 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM net > + > +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NET_H > + > +#include > +#include > +#include > +#include > + > +TRACE_EVENT(net_dev_xmit, > + > + TP_PROTO(struct sk_buff *skb, > + int rc, > + struct net_device *dev, > + unsigned int skb_len), > + > + TP_ARGS(skb, rc, dev, skb_len), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __field( int, rc ) > + __string( name, dev->name ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->len = skb_len; > + __entry->rc = rc; > + __assign_str(name, dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", > + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) > +); > + > +DECLARE_EVENT_CLASS(net_dev_template, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __string( name, skb->dev->name ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->len = skb->len; > + __assign_str(name, skb->dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u", > + __get_str(name), __entry->skbaddr, __entry->len) > +) > + > +DEFINE_EVENT(net_dev_template, net_dev_queue, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +); > + > +DEFINE_EVENT(net_dev_template, netif_receive_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +); > + > +DEFINE_EVENT(net_dev_template, netif_rx, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +); > +#endif /* _TRACE_NET_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/power.h b/instrumentation/events/mainline/power.h > new file mode 100644 > index 0000000..1bcc2a8 > --- /dev/null > +++ b/instrumentation/events/mainline/power.h > @@ -0,0 +1,240 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM power > + > +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_POWER_H > + > +#include > +#include > + > +DECLARE_EVENT_CLASS(cpu, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + __field( u32, cpu_id ) > + ), > + > + TP_fast_assign( > + __entry->state = state; > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, > + (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(cpu, cpu_idle, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id) > +); > + > +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING > + > +#define PWR_EVENT_EXIT -1 > +#endif > + > +DEFINE_EVENT(cpu, cpu_frequency, > + > + TP_PROTO(unsigned int frequency, unsigned int cpu_id), > + > + TP_ARGS(frequency, cpu_id) > +); > + > +TRACE_EVENT(machine_suspend, > + > + TP_PROTO(unsigned int state), > + > + TP_ARGS(state), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + ), > + > + TP_fast_assign( > + __entry->state = state; > + ), > + > + TP_printk("state=%lu", (unsigned long)__entry->state) > +); > + > +/* This code will be removed after deprecation time exceeded (2.6.41) */ > +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED > + > +/* > + * The power events are used for cpuidle & suspend (power_start, power_end) > + * and for cpufreq (power_frequency) > + */ > +DECLARE_EVENT_CLASS(power, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, type ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __entry->type = type; > + __entry->state = state; > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(power, power_start, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +); > + > +DEFINE_EVENT(power, power_frequency, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +); > + > +TRACE_EVENT(power_end, > + > + TP_PROTO(unsigned int cpu_id), > + > + TP_ARGS(cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) > + > +); > + > +/* Deprecated dummy functions must be protected against multi-declartion */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > + > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > + > +/* These dummy declaration have to be ripped out when the deprecated > + events get removed */ > +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; > +static inline void trace_power_end(u64 cpuid) {}; > +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +/* > + * The clock events are used for clock enable/disable and for > + * clock rate change > + */ > +DECLARE_EVENT_CLASS(clock, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->state = state; > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(clock, clock_enable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > + > +DEFINE_EVENT(clock, clock_disable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > + > +DEFINE_EVENT(clock, clock_set_rate, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > + > +/* > + * The power domain events are used for power domains transitions > + */ > +DECLARE_EVENT_CLASS(power_domain, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->state = state; > + __entry->cpu_id = cpu_id; > +), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(power_domain, power_domain_target, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/regulator.h b/instrumentation/events/mainline/regulator.h > new file mode 100644 > index 0000000..37502a7 > --- /dev/null > +++ b/instrumentation/events/mainline/regulator.h > @@ -0,0 +1,141 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM regulator > + > +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_REGULATOR_H > + > +#include > +#include > + > +/* > + * Events which just log themselves and the regulator name for enable/disable > + * type tracking. > + */ > +DECLARE_EVENT_CLASS(regulator_basic, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + ), > + > + TP_printk("name=%s", __get_str(name)) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_enable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_enable_delay, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_enable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_disable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_disable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +/* > + * Events that take a range of numerical values, mostly for voltages > + * and so on. > + */ > +DECLARE_EVENT_CLASS(regulator_range, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( int, min ) > + __field( int, max ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->min = min; > + __entry->max = max; > + ), > + > + TP_printk("name=%s (%d-%d)", __get_str(name), > + (int)__entry->min, (int)__entry->max) > +); > + > +DEFINE_EVENT(regulator_range, regulator_set_voltage, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max) > + > +); > + > + > +/* > + * Events that take a single value, mostly for readback and refcounts. > + */ > +DECLARE_EVENT_CLASS(regulator_value, > + > + TP_PROTO(const char *name, unsigned int val), > + > + TP_ARGS(name, val), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->val = val; > + ), > + > + TP_printk("name=%s, val=%u", __get_str(name), > + (int)__entry->val) > +); > + > +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, > + > + TP_PROTO(const char *name, unsigned int value), > + > + TP_ARGS(name, value) > + > +); > + > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/scsi.h b/instrumentation/events/mainline/scsi.h > new file mode 100644 > index 0000000..db6c935 > --- /dev/null > +++ b/instrumentation/events/mainline/scsi.h > @@ -0,0 +1,365 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM scsi > + > +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SCSI_H > + > +#include > +#include > +#include > +#include > + > +#define scsi_opcode_name(opcode) { opcode, #opcode } > +#define show_opcode_name(val) \ > + __print_symbolic(val, \ > + scsi_opcode_name(TEST_UNIT_READY), \ > + scsi_opcode_name(REZERO_UNIT), \ > + scsi_opcode_name(REQUEST_SENSE), \ > + scsi_opcode_name(FORMAT_UNIT), \ > + scsi_opcode_name(READ_BLOCK_LIMITS), \ > + scsi_opcode_name(REASSIGN_BLOCKS), \ > + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ > + scsi_opcode_name(READ_6), \ > + scsi_opcode_name(WRITE_6), \ > + scsi_opcode_name(SEEK_6), \ > + scsi_opcode_name(READ_REVERSE), \ > + scsi_opcode_name(WRITE_FILEMARKS), \ > + scsi_opcode_name(SPACE), \ > + scsi_opcode_name(INQUIRY), \ > + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ > + scsi_opcode_name(MODE_SELECT), \ > + scsi_opcode_name(RESERVE), \ > + scsi_opcode_name(RELEASE), \ > + scsi_opcode_name(COPY), \ > + scsi_opcode_name(ERASE), \ > + scsi_opcode_name(MODE_SENSE), \ > + scsi_opcode_name(START_STOP), \ > + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ > + scsi_opcode_name(SEND_DIAGNOSTIC), \ > + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ > + scsi_opcode_name(SET_WINDOW), \ > + scsi_opcode_name(READ_CAPACITY), \ > + scsi_opcode_name(READ_10), \ > + scsi_opcode_name(WRITE_10), \ > + scsi_opcode_name(SEEK_10), \ > + scsi_opcode_name(POSITION_TO_ELEMENT), \ > + scsi_opcode_name(WRITE_VERIFY), \ > + scsi_opcode_name(VERIFY), \ > + scsi_opcode_name(SEARCH_HIGH), \ > + scsi_opcode_name(SEARCH_EQUAL), \ > + scsi_opcode_name(SEARCH_LOW), \ > + scsi_opcode_name(SET_LIMITS), \ > + scsi_opcode_name(PRE_FETCH), \ > + scsi_opcode_name(READ_POSITION), \ > + scsi_opcode_name(SYNCHRONIZE_CACHE), \ > + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ > + scsi_opcode_name(READ_DEFECT_DATA), \ > + scsi_opcode_name(MEDIUM_SCAN), \ > + scsi_opcode_name(COMPARE), \ > + scsi_opcode_name(COPY_VERIFY), \ > + scsi_opcode_name(WRITE_BUFFER), \ > + scsi_opcode_name(READ_BUFFER), \ > + scsi_opcode_name(UPDATE_BLOCK), \ > + scsi_opcode_name(READ_LONG), \ > + scsi_opcode_name(WRITE_LONG), \ > + scsi_opcode_name(CHANGE_DEFINITION), \ > + scsi_opcode_name(WRITE_SAME), \ > + scsi_opcode_name(UNMAP), \ > + scsi_opcode_name(READ_TOC), \ > + scsi_opcode_name(LOG_SELECT), \ > + scsi_opcode_name(LOG_SENSE), \ > + scsi_opcode_name(XDWRITEREAD_10), \ > + scsi_opcode_name(MODE_SELECT_10), \ > + scsi_opcode_name(RESERVE_10), \ > + scsi_opcode_name(RELEASE_10), \ > + scsi_opcode_name(MODE_SENSE_10), \ > + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ > + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ > + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ > + scsi_opcode_name(REPORT_LUNS), \ > + scsi_opcode_name(MAINTENANCE_IN), \ > + scsi_opcode_name(MAINTENANCE_OUT), \ > + scsi_opcode_name(MOVE_MEDIUM), \ > + scsi_opcode_name(EXCHANGE_MEDIUM), \ > + scsi_opcode_name(READ_12), \ > + scsi_opcode_name(WRITE_12), \ > + scsi_opcode_name(WRITE_VERIFY_12), \ > + scsi_opcode_name(SEARCH_HIGH_12), \ > + scsi_opcode_name(SEARCH_EQUAL_12), \ > + scsi_opcode_name(SEARCH_LOW_12), \ > + scsi_opcode_name(READ_ELEMENT_STATUS), \ > + scsi_opcode_name(SEND_VOLUME_TAG), \ > + scsi_opcode_name(WRITE_LONG_2), \ > + scsi_opcode_name(READ_16), \ > + scsi_opcode_name(WRITE_16), \ > + scsi_opcode_name(VERIFY_16), \ > + scsi_opcode_name(WRITE_SAME_16), \ > + scsi_opcode_name(SERVICE_ACTION_IN), \ > + scsi_opcode_name(SAI_READ_CAPACITY_16), \ > + scsi_opcode_name(SAI_GET_LBA_STATUS), \ > + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ > + scsi_opcode_name(MO_SET_TARGET_PGS), \ > + scsi_opcode_name(READ_32), \ > + scsi_opcode_name(WRITE_32), \ > + scsi_opcode_name(WRITE_SAME_32), \ > + scsi_opcode_name(ATA_16), \ > + scsi_opcode_name(ATA_12)) > + > +#define scsi_hostbyte_name(result) { result, #result } > +#define show_hostbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_hostbyte_name(DID_OK), \ > + scsi_hostbyte_name(DID_NO_CONNECT), \ > + scsi_hostbyte_name(DID_BUS_BUSY), \ > + scsi_hostbyte_name(DID_TIME_OUT), \ > + scsi_hostbyte_name(DID_BAD_TARGET), \ > + scsi_hostbyte_name(DID_ABORT), \ > + scsi_hostbyte_name(DID_PARITY), \ > + scsi_hostbyte_name(DID_ERROR), \ > + scsi_hostbyte_name(DID_RESET), \ > + scsi_hostbyte_name(DID_BAD_INTR), \ > + scsi_hostbyte_name(DID_PASSTHROUGH), \ > + scsi_hostbyte_name(DID_SOFT_ERROR), \ > + scsi_hostbyte_name(DID_IMM_RETRY), \ > + scsi_hostbyte_name(DID_REQUEUE), \ > + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ > + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) > + > +#define scsi_driverbyte_name(result) { result, #result } > +#define show_driverbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_driverbyte_name(DRIVER_OK), \ > + scsi_driverbyte_name(DRIVER_BUSY), \ > + scsi_driverbyte_name(DRIVER_SOFT), \ > + scsi_driverbyte_name(DRIVER_MEDIA), \ > + scsi_driverbyte_name(DRIVER_ERROR), \ > + scsi_driverbyte_name(DRIVER_INVALID), \ > + scsi_driverbyte_name(DRIVER_TIMEOUT), \ > + scsi_driverbyte_name(DRIVER_HARD), \ > + scsi_driverbyte_name(DRIVER_SENSE)) > + > +#define scsi_msgbyte_name(result) { result, #result } > +#define show_msgbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_msgbyte_name(COMMAND_COMPLETE), \ > + scsi_msgbyte_name(EXTENDED_MESSAGE), \ > + scsi_msgbyte_name(SAVE_POINTERS), \ > + scsi_msgbyte_name(RESTORE_POINTERS), \ > + scsi_msgbyte_name(DISCONNECT), \ > + scsi_msgbyte_name(INITIATOR_ERROR), \ > + scsi_msgbyte_name(ABORT_TASK_SET), \ > + scsi_msgbyte_name(MESSAGE_REJECT), \ > + scsi_msgbyte_name(NOP), \ > + scsi_msgbyte_name(MSG_PARITY_ERROR), \ > + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ > + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ > + scsi_msgbyte_name(TARGET_RESET), \ > + scsi_msgbyte_name(ABORT_TASK), \ > + scsi_msgbyte_name(CLEAR_TASK_SET), \ > + scsi_msgbyte_name(INITIATE_RECOVERY), \ > + scsi_msgbyte_name(RELEASE_RECOVERY), \ > + scsi_msgbyte_name(CLEAR_ACA), \ > + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ > + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ > + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ > + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ > + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ > + scsi_msgbyte_name(ACA), \ > + scsi_msgbyte_name(QAS_REQUEST), \ > + scsi_msgbyte_name(BUS_DEVICE_RESET), \ > + scsi_msgbyte_name(ABORT)) > + > +#define scsi_statusbyte_name(result) { result, #result } > +#define show_statusbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_statusbyte_name(SAM_STAT_GOOD), \ > + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ > + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_BUSY), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ > + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ > + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ > + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ > + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) > + > +#define scsi_prot_op_name(result) { result, #result } > +#define show_prot_op_name(val) \ > + __print_symbolic(val, \ > + scsi_prot_op_name(SCSI_PROT_NORMAL), \ > + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) > + > +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); > +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) > + > +TRACE_EVENT(scsi_dispatch_cmd_start, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + __entry->host_no = cmd->device->host->host_no; > + __entry->channel = cmd->device->channel; > + __entry->id = cmd->device->id; > + __entry->lun = cmd->device->lun; > + __entry->opcode = cmd->cmnd[0]; > + __entry->cmd_len = cmd->cmd_len; > + __entry->data_sglen = scsi_sg_count(cmd); > + __entry->prot_sglen = scsi_prot_sg_count(cmd); > + __entry->prot_op = scsi_get_prot_op(cmd); > + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) > +); > + > +TRACE_EVENT(scsi_dispatch_cmd_error, > + > + TP_PROTO(struct scsi_cmnd *cmd, int rtn), > + > + TP_ARGS(cmd, rtn), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, rtn ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + __entry->host_no = cmd->device->host->host_no; > + __entry->channel = cmd->device->channel; > + __entry->id = cmd->device->id; > + __entry->lun = cmd->device->lun; > + __entry->rtn = rtn; > + __entry->opcode = cmd->cmnd[0]; > + __entry->cmd_len = cmd->cmd_len; > + __entry->data_sglen = scsi_sg_count(cmd); > + __entry->prot_sglen = scsi_prot_sg_count(cmd); > + __entry->prot_op = scsi_get_prot_op(cmd); > + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + __entry->rtn) > +); > + > +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, result ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + __entry->host_no = cmd->device->host->host_no; > + __entry->channel = cmd->device->channel; > + __entry->id = cmd->device->id; > + __entry->lun = cmd->device->lun; > + __entry->result = cmd->result; > + __entry->opcode = cmd->cmnd[0]; > + __entry->cmd_len = cmd->cmd_len; > + __entry->data_sglen = scsi_sg_count(cmd); > + __entry->prot_sglen = scsi_prot_sg_count(cmd); > + __entry->prot_op = scsi_get_prot_op(cmd); > + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ > + "%s host=%s message=%s status=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + show_driverbyte_name(((__entry->result) >> 24) & 0xff), > + show_hostbyte_name(((__entry->result) >> 16) & 0xff), > + show_msgbyte_name(((__entry->result) >> 8) & 0xff), > + show_statusbyte_name(__entry->result & 0xff)) > +); > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)); > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)); > + > +TRACE_EVENT(scsi_eh_wakeup, > + > + TP_PROTO(struct Scsi_Host *shost), > + > + TP_ARGS(shost), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + ), > + > + TP_fast_assign( > + __entry->host_no = shost->host_no; > + ), > + > + TP_printk("host_no=%u", __entry->host_no) > +); > + > +#endif /* _TRACE_SCSI_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/skb.h b/instrumentation/events/mainline/skb.h > new file mode 100644 > index 0000000..0c68ae2 > --- /dev/null > +++ b/instrumentation/events/mainline/skb.h > @@ -0,0 +1,75 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM skb > + > +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SKB_H > + > +#include > +#include > +#include > + > +/* > + * Tracepoint for free an sk_buff: > + */ > +TRACE_EVENT(kfree_skb, > + > + TP_PROTO(struct sk_buff *skb, void *location), > + > + TP_ARGS(skb, location), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( void *, location ) > + __field( unsigned short, protocol ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->location = location; > + __entry->protocol = ntohs(skb->protocol); > + ), > + > + TP_printk("skbaddr=%p protocol=%u location=%p", > + __entry->skbaddr, __entry->protocol, __entry->location) > +); > + > +TRACE_EVENT(consume_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + ), > + > + TP_printk("skbaddr=%p", __entry->skbaddr) > +); > + > +TRACE_EVENT(skb_copy_datagram_iovec, > + > + TP_PROTO(const struct sk_buff *skb, int len), > + > + TP_ARGS(skb, len), > + > + TP_STRUCT__entry( > + __field( const void *, skbaddr ) > + __field( int, len ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->len = len; > + ), > + > + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) > +); > + > +#endif /* _TRACE_SKB_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/sock.h b/instrumentation/events/mainline/sock.h > new file mode 100644 > index 0000000..779abb9 > --- /dev/null > +++ b/instrumentation/events/mainline/sock.h > @@ -0,0 +1,68 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM sock > + > +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SOCK_H > + > +#include > +#include > + > +TRACE_EVENT(sock_rcvqueue_full, > + > + TP_PROTO(struct sock *sk, struct sk_buff *skb), > + > + TP_ARGS(sk, skb), > + > + TP_STRUCT__entry( > + __field(int, rmem_alloc) > + __field(unsigned int, truesize) > + __field(int, sk_rcvbuf) > + ), > + > + TP_fast_assign( > + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); > + __entry->truesize = skb->truesize; > + __entry->sk_rcvbuf = sk->sk_rcvbuf; > + ), > + > + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", > + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) > +); > + > +TRACE_EVENT(sock_exceed_buf_limit, > + > + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), > + > + TP_ARGS(sk, prot, allocated), > + > + TP_STRUCT__entry( > + __array(char, name, 32) > + __field(long *, sysctl_mem) > + __field(long, allocated) > + __field(int, sysctl_rmem) > + __field(int, rmem_alloc) > + ), > + > + TP_fast_assign( > + strncpy(__entry->name, prot->name, 32); > + __entry->sysctl_mem = prot->sysctl_mem; > + __entry->allocated = allocated; > + __entry->sysctl_rmem = prot->sysctl_rmem[0]; > + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); > + ), > + > + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " > + "sysctl_rmem=%d rmem_alloc=%d", > + __entry->name, > + __entry->sysctl_mem[0], > + __entry->sysctl_mem[1], > + __entry->sysctl_mem[2], > + __entry->allocated, > + __entry->sysctl_rmem, > + __entry->rmem_alloc) > +); > + > +#endif /* _TRACE_SOCK_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/udp.h b/instrumentation/events/mainline/udp.h > new file mode 100644 > index 0000000..a664bb9 > --- /dev/null > +++ b/instrumentation/events/mainline/udp.h > @@ -0,0 +1,32 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM udp > + > +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_UDP_H > + > +#include > +#include > + > +TRACE_EVENT(udp_fail_queue_rcv_skb, > + > + TP_PROTO(int rc, struct sock *sk), > + > + TP_ARGS(rc, sk), > + > + TP_STRUCT__entry( > + __field(int, rc) > + __field(__u16, lport) > + ), > + > + TP_fast_assign( > + __entry->rc = rc; > + __entry->lport = inet_sk(sk)->inet_num; > + ), > + > + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) > +); > + > +#endif /* _TRACE_UDP_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/vmscan.h b/instrumentation/events/mainline/vmscan.h > new file mode 100644 > index 0000000..36851f7 > --- /dev/null > +++ b/instrumentation/events/mainline/vmscan.h > @@ -0,0 +1,477 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM vmscan > + > +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_VMSCAN_H > + > +#include > +#include > +#include > +#include > +#include "gfpflags.h" > + > +#define RECLAIM_WB_ANON 0x0001u > +#define RECLAIM_WB_FILE 0x0002u > +#define RECLAIM_WB_MIXED 0x0010u > +#define RECLAIM_WB_SYNC 0x0004u > +#define RECLAIM_WB_ASYNC 0x0008u > + > +#define show_reclaim_flags(flags) \ > + (flags) ? __print_flags(flags, "|", \ > + {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ > + {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ > + {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ > + {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ > + {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ > + ) : "RECLAIM_WB_NONE" > + > +#define trace_reclaim_flags(page, sync) ( \ > + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + ) > + > +#define trace_shrink_flags(file, sync) ( \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ > + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + ) > + > +TRACE_EVENT(mm_vmscan_kswapd_sleep, > + > + TP_PROTO(int nid), > + > + TP_ARGS(nid), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + ), > + > + TP_printk("nid=%d", __entry->nid) > +); > + > +TRACE_EVENT(mm_vmscan_kswapd_wake, > + > + TP_PROTO(int nid, int order), > + > + TP_ARGS(nid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + __entry->order = order; > + ), > + > + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) > +); > + > +TRACE_EVENT(mm_vmscan_wakeup_kswapd, > + > + TP_PROTO(int nid, int zid, int order), > + > + TP_ARGS(nid, zid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, zid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + __entry->zid = zid; > + __entry->order = order; > + ), > + > + TP_printk("nid=%d zid=%d order=%d", > + __entry->nid, > + __entry->zid, > + __entry->order) > +); > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags), > + > + TP_STRUCT__entry( > + __field( int, order ) > + __field( int, may_writepage ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + __entry->order = order; > + __entry->may_writepage = may_writepage; > + __entry->gfp_flags = gfp_flags; > + ), > + > + TP_printk("order=%d may_writepage=%d gfp_flags=%s", > + __entry->order, > + __entry->may_writepage, > + show_gfp_flags(__entry->gfp_flags)) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +); > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed), > + > + TP_STRUCT__entry( > + __field( unsigned long, nr_reclaimed ) > + ), > + > + TP_fast_assign( > + __entry->nr_reclaimed = nr_reclaimed; > + ), > + > + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +); > + > +TRACE_EVENT(mm_shrink_slab_start, > + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, > + long nr_objects_to_shrink, unsigned long pgs_scanned, > + unsigned long lru_pgs, unsigned long cache_items, > + unsigned long long delta, unsigned long total_scan), > + > + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, > + cache_items, delta, total_scan), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, nr_objects_to_shrink) > + __field(gfp_t, gfp_flags) > + __field(unsigned long, pgs_scanned) > + __field(unsigned long, lru_pgs) > + __field(unsigned long, cache_items) > + __field(unsigned long long, delta) > + __field(unsigned long, total_scan) > + ), > + > + TP_fast_assign( > + __entry->shr = shr; > + __entry->shrink = shr->shrink; > + __entry->nr_objects_to_shrink = nr_objects_to_shrink; > + __entry->gfp_flags = sc->gfp_mask; > + __entry->pgs_scanned = pgs_scanned; > + __entry->lru_pgs = lru_pgs; > + __entry->cache_items = cache_items; > + __entry->delta = delta; > + __entry->total_scan = total_scan; > + ), > + > + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", > + __entry->shrink, > + __entry->shr, > + __entry->nr_objects_to_shrink, > + show_gfp_flags(__entry->gfp_flags), > + __entry->pgs_scanned, > + __entry->lru_pgs, > + __entry->cache_items, > + __entry->delta, > + __entry->total_scan) > +); > + > +TRACE_EVENT(mm_shrink_slab_end, > + TP_PROTO(struct shrinker *shr, int shrinker_retval, > + long unused_scan_cnt, long new_scan_cnt), > + > + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, unused_scan) > + __field(long, new_scan) > + __field(int, retval) > + __field(long, total_scan) > + ), > + > + TP_fast_assign( > + __entry->shr = shr; > + __entry->shrink = shr->shrink; > + __entry->unused_scan = unused_scan_cnt; > + __entry->new_scan = new_scan_cnt; > + __entry->retval = shrinker_retval; > + __entry->total_scan = new_scan_cnt - unused_scan_cnt; > + ), > + > + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", > + __entry->shrink, > + __entry->shr, > + __entry->unused_scan, > + __entry->new_scan, > + __entry->total_scan, > + __entry->retval) > +); > + > +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > + int isolate_mode), > + > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), > + > + TP_STRUCT__entry( > + __field(int, order) > + __field(unsigned long, nr_requested) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_taken) > + __field(unsigned long, nr_lumpy_taken) > + __field(unsigned long, nr_lumpy_dirty) > + __field(unsigned long, nr_lumpy_failed) > + __field(int, isolate_mode) > + ), > + > + TP_fast_assign( > + __entry->order = order; > + __entry->nr_requested = nr_requested; > + __entry->nr_scanned = nr_scanned; > + __entry->nr_taken = nr_taken; > + __entry->nr_lumpy_taken = nr_lumpy_taken; > + __entry->nr_lumpy_dirty = nr_lumpy_dirty; > + __entry->nr_lumpy_failed = nr_lumpy_failed; > + __entry->isolate_mode = isolate_mode; > + ), > + > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", > + __entry->isolate_mode, > + __entry->order, > + __entry->nr_requested, > + __entry->nr_scanned, > + __entry->nr_taken, > + __entry->nr_lumpy_taken, > + __entry->nr_lumpy_dirty, > + __entry->nr_lumpy_failed) > +); > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > + int isolate_mode), > + > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > + > +); > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > + int isolate_mode), > + > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > + > +); > + > +TRACE_EVENT(mm_vmscan_writepage, > + > + TP_PROTO(struct page *page, > + int reclaim_flags), > + > + TP_ARGS(page, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(struct page *, page) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->reclaim_flags = reclaim_flags; > + ), > + > + TP_printk("page=%p pfn=%lu flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + show_reclaim_flags(__entry->reclaim_flags)) > +); > + > +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > + > + TP_PROTO(int nid, int zid, > + unsigned long nr_scanned, unsigned long nr_reclaimed, > + int priority, int reclaim_flags), > + > + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(int, nid) > + __field(int, zid) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_reclaimed) > + __field(int, priority) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + __entry->zid = zid; > + __entry->nr_scanned = nr_scanned; > + __entry->nr_reclaimed = nr_reclaimed; > + __entry->priority = priority; > + __entry->reclaim_flags = reclaim_flags; > + ), > + > + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", > + __entry->nid, __entry->zid, > + __entry->nr_scanned, __entry->nr_reclaimed, > + __entry->priority, > + show_reclaim_flags(__entry->reclaim_flags)) > +); > + > +TRACE_EVENT(replace_swap_token, > + TP_PROTO(struct mm_struct *old_mm, > + struct mm_struct *new_mm), > + > + TP_ARGS(old_mm, new_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, old_mm) > + __field(unsigned int, old_prio) > + __field(struct mm_struct*, new_mm) > + __field(unsigned int, new_prio) > + ), > + > + TP_fast_assign( > + __entry->old_mm = old_mm; > + __entry->old_prio = old_mm ? old_mm->token_priority : 0; > + __entry->new_mm = new_mm; > + __entry->new_prio = new_mm->token_priority; > + ), > + > + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", > + __entry->old_mm, __entry->old_prio, > + __entry->new_mm, __entry->new_prio) > +); > + > +DECLARE_EVENT_CLASS(put_swap_token_template, > + TP_PROTO(struct mm_struct *swap_token_mm), > + > + TP_ARGS(swap_token_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, swap_token_mm) > + ), > + > + TP_fast_assign( > + __entry->swap_token_mm = swap_token_mm; > + ), > + > + TP_printk("token_mm=%p", __entry->swap_token_mm) > +); > + > +DEFINE_EVENT(put_swap_token_template, put_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm) > +); > + > +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm), > + TP_CONDITION(swap_token_mm != NULL) > +); > + > +TRACE_EVENT_CONDITION(update_swap_token_priority, > + TP_PROTO(struct mm_struct *mm, > + unsigned int old_prio, > + struct mm_struct *swap_token_mm), > + > + TP_ARGS(mm, old_prio, swap_token_mm), > + > + TP_CONDITION(mm->token_priority != old_prio), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, mm) > + __field(unsigned int, old_prio) > + __field(unsigned int, new_prio) > + __field(struct mm_struct*, swap_token_mm) > + __field(unsigned int, swap_token_prio) > + ), > + > + TP_fast_assign( > + __entry->mm = mm; > + __entry->old_prio = old_prio; > + __entry->new_prio = mm->token_priority; > + __entry->swap_token_mm = swap_token_mm; > + __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0; > + ), > + > + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", > + __entry->mm, __entry->old_prio, __entry->new_prio, > + __entry->swap_token_mm, __entry->swap_token_prio) > +); > + > +#endif /* _TRACE_VMSCAN_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/probes/Makefile b/probes/Makefile > index 6efd6ad..c39a84a 100644 > --- a/probes/Makefile > +++ b/probes/Makefile > @@ -12,6 +12,9 @@ obj-m += lttng-probe-lttng.o > obj-m += lttng-probe-sched.o > obj-m += lttng-probe-irq.o > obj-m += lttng-probe-timer.o > +obj-m += lttng-probe-kmem.o > +obj-m += lttng-probe-module.o > +obj-m += lttng-probe-power.o > > obj-m += lttng-probe-statedump.o > > @@ -33,6 +36,75 @@ obj-m += $(shell \ > endif > endif > > +ifneq ($(CONFIG_NET),) > +obj-m += lttng-probe-net.o > +obj-m += lttng-probe-napi.o > +obj-m += lttng-probe-skb.o > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-sock.o" ; fi;) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-udp.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_SND_SOC),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ > + echo "lttng-probe-asoc.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_EXT3_FS),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-ext3.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_GPIOLIB),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 ] ; then \ > + echo "lttng-probe-gpio.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_JBD2),) > +obj-m += lttng-probe-jbd2.o > +endif > + > +ifneq ($(CONFIG_JBD),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-jbd.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_REGULATOR),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ > + echo "lttng-probe-regulator.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_SCSI),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 ] ; then \ > + echo "lttng-probe-scsi.o" ; fi;) > +endif > + > +vmscan = $(shell \ > + if [ $(VERSION) -ge 3 ] ; then \ > + echo "lttng-probe-vmscan.o" ; fi;) > +ifneq ($(CONFIG_SWAP),) > + obj-m += $(vmscan) > +else > +ifneq ($(CONFIG_CGROUP_MEM_RES_CTLR),) > + obj-m += $(vmscan) > +endif > +endif > + > +ifneq ($(CONFIG_LOCKDEP),) > +obj-m += lttng-probe-lock.o > +endif > + > ifneq ($(CONFIG_KPROBES),) > obj-m += lttng-kprobes.o > endif > diff --git a/probes/lttng-probe-asoc.c b/probes/lttng-probe-asoc.c > new file mode 100644 > index 0000000..427639f > --- /dev/null > +++ b/probes/lttng-probe-asoc.c > @@ -0,0 +1,45 @@ > +/* > + * probes/lttng-probe-block.c > + * > + * LTTng asoc probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/asoc.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng asoc probes"); > diff --git a/probes/lttng-probe-ext3.c b/probes/lttng-probe-ext3.c > new file mode 100644 > index 0000000..0df2b67 > --- /dev/null > +++ b/probes/lttng-probe-ext3.c > @@ -0,0 +1,56 @@ > +/* > + * probes/lttng-probe-ext3.c > + * > + * LTTng ext3 probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > +#include > + > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > +/* > + * Since 3.4 the is no linux/ext3_fs_i.h anymore. Instead we have to use > + * ext3.h from fs/ext3/ext3.h (which also includes trace/events/ext3.h) > + */ > +#include "../instrumentation/events/mainline/fs_ext3.h" > +#else > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > +#endif > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/ext3.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng ext3 probes"); > diff --git a/probes/lttng-probe-gpio.c b/probes/lttng-probe-gpio.c > new file mode 100644 > index 0000000..51692a7 > --- /dev/null > +++ b/probes/lttng-probe-gpio.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-gpio.c > + * > + * LTTng gpio probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/gpio.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng gpio probes"); > diff --git a/probes/lttng-probe-jbd.c b/probes/lttng-probe-jbd.c > new file mode 100644 > index 0000000..46911cc > --- /dev/null > +++ b/probes/lttng-probe-jbd.c > @@ -0,0 +1,44 @@ > +/* > + * probes/lttng-probe-jbd.c > + * > + * LTTng jbd probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/jbd.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng jbd probes"); > diff --git a/probes/lttng-probe-jbd2.c b/probes/lttng-probe-jbd2.c > new file mode 100644 > index 0000000..eea0a66 > --- /dev/null > +++ b/probes/lttng-probe-jbd2.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-jbd2.c > + * > + * LTTng jbd2 probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/jbd2.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng jbd2 probes"); > diff --git a/probes/lttng-probe-kmem.c b/probes/lttng-probe-kmem.c > new file mode 100644 > index 0000000..af67759 > --- /dev/null > +++ b/probes/lttng-probe-kmem.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-kmem.c > + * > + * LTTng kmem probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/kmem.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng kmem probes"); > diff --git a/probes/lttng-probe-lock.c b/probes/lttng-probe-lock.c > new file mode 100644 > index 0000000..16ac0e7 > --- /dev/null > +++ b/probes/lttng-probe-lock.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-lock.c > + * > + * LTTng lock probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/lock.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng lock probes"); > diff --git a/probes/lttng-probe-module.c b/probes/lttng-probe-module.c > new file mode 100644 > index 0000000..1a3c255 > --- /dev/null > +++ b/probes/lttng-probe-module.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-module.c > + * > + * LTTng module probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/module.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng module probes"); > diff --git a/probes/lttng-probe-napi.c b/probes/lttng-probe-napi.c > new file mode 100644 > index 0000000..cae8504 > --- /dev/null > +++ b/probes/lttng-probe-napi.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-napi.c > + * > + * LTTng napi probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/napi.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng napi probes"); > diff --git a/probes/lttng-probe-net.c b/probes/lttng-probe-net.c > new file mode 100644 > index 0000000..54212be > --- /dev/null > +++ b/probes/lttng-probe-net.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-net.c > + * > + * LTTng net probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/net.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng net probes"); > diff --git a/probes/lttng-probe-power.c b/probes/lttng-probe-power.c > new file mode 100644 > index 0000000..5dcb93f > --- /dev/null > +++ b/probes/lttng-probe-power.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-power.c > + * > + * LTTng power probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/power.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng power probes"); > diff --git a/probes/lttng-probe-regulator.c b/probes/lttng-probe-regulator.c > new file mode 100644 > index 0000000..7c8b7f9 > --- /dev/null > +++ b/probes/lttng-probe-regulator.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-regulator.c > + * > + * LTTng regulator probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/regulator.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng regulator probes"); > diff --git a/probes/lttng-probe-scsi.c b/probes/lttng-probe-scsi.c > new file mode 100644 > index 0000000..51702c3 > --- /dev/null > +++ b/probes/lttng-probe-scsi.c > @@ -0,0 +1,44 @@ > +/* > + * probes/lttng-probe-scsi.c > + * > + * LTTng scsi probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/scsi.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng scsi probes"); > diff --git a/probes/lttng-probe-skb.c b/probes/lttng-probe-skb.c > new file mode 100644 > index 0000000..52edf88 > --- /dev/null > +++ b/probes/lttng-probe-skb.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-skb.c > + * > + * LTTng skb probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/skb.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng skb probes"); > diff --git a/probes/lttng-probe-sock.c b/probes/lttng-probe-sock.c > new file mode 100644 > index 0000000..b3e699a > --- /dev/null > +++ b/probes/lttng-probe-sock.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-sock.c > + * > + * LTTng sock probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/sock.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng sock probes"); > diff --git a/probes/lttng-probe-udp.c b/probes/lttng-probe-udp.c > new file mode 100644 > index 0000000..51ec3cb > --- /dev/null > +++ b/probes/lttng-probe-udp.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-udp.c > + * > + * LTTng udp probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/udp.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng udp probes"); > diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c > new file mode 100644 > index 0000000..2abd0e4 > --- /dev/null > +++ b/probes/lttng-probe-vmscan.c > @@ -0,0 +1,48 @@ > +/* > + * probes/lttng-probe-vmscan.c > + * > + * LTTng vmscan probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) > +typedef int isolate_mode_t; > +#endif > + > +#include "../instrumentation/events/lttng-module/vmscan.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng vmscan probes"); > -- > 1.7.10.4 > > > > -- > Paul Woegerer | SW Development Engineer > http://go.mentor.com/sourceryanalyzer > > Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria > Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS > > Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. > Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Mon Nov 12 10:36:14 2012 From: dgoulet at efficios.com (David Goulet) Date: Mon, 12 Nov 2012 10:36:14 -0500 Subject: [lttng-dev] [PATCH 1/2] Add default subbuf sizes getter functions In-Reply-To: <1352694514-25027-1-git-send-email-simon.marchi@polymtl.ca> References: <1352694514-25027-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <50A1176E.4070302@efficios.com> Yes +1 for the inline so I'll let you resubmit and fix the dot on the last patch. Thanks! David Simon Marchi: > This patch adds src/common/defaults.c file. It contains functions to > retrieve defaults subbuf sizes. It uses the DEFAULT_*_SUBBUF_SIZE > defines from defaults.h but also make sure that the values are at least > as big as the page size. > > Signed-off-by: Simon Marchi > --- > src/common/Makefile.am | 2 +- > src/common/defaults.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ > src/common/defaults.h | 7 ++++ > 3 files changed, 99 insertions(+), 1 deletions(-) > create mode 100644 src/common/defaults.c > > diff --git a/src/common/Makefile.am b/src/common/Makefile.am > index b43b376..f91259c 100644 > --- a/src/common/Makefile.am > +++ b/src/common/Makefile.am > @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ > noinst_LTLIBRARIES = libcommon.la > > libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ > - common.h futex.c futex.h uri.c uri.h > + common.h futex.c futex.h uri.c uri.h defaults.c > > # Consumer library > noinst_LTLIBRARIES += libconsumer.la > diff --git a/src/common/defaults.c b/src/common/defaults.c > new file mode 100644 > index 0000000..cde4fb9 > --- /dev/null > +++ b/src/common/defaults.c > @@ -0,0 +1,91 @@ > +/* > + * Copyright (C) 2012 - Simon Marchi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License, version 2 only, > + * as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include > +#include > + > +#include "defaults.h" > + > +#ifndef max > +#define max(a, b) ((a) > (b) ? (a) : (b)) > +#endif > + > +static size_t default_channel_subbuf_size; > +static size_t default_metadata_subbuf_size; > +static size_t default_kernel_channel_subbuf_size; > +static size_t default_ust_channel_subbuf_size; > + > +static void __attribute__((constructor)) init_defaults(void) > +{ > + /* libringbuffer won't accept subbuf sizes smaller than the page size, > + * so. If the default subbuf size is smaller, replace it by the page > + * size. */ > + long page_size = sysconf(_SC_PAGESIZE); > + > + if (page_size < 0) { > + page_size = 0; > + } > + > + default_channel_subbuf_size = max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); > + default_metadata_subbuf_size = max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); > + default_kernel_channel_subbuf_size = max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); > + default_ust_channel_subbuf_size = max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); > +} > + > +/* > + * Returns the default subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t default_get_channel_subbuf_size(void) > +{ > + return default_channel_subbuf_size; > +} > + > +/* > + * Returns the default metadata subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t default_get_metadata_subbuf_size(void) > +{ > + return default_metadata_subbuf_size; > +} > + > +/* > + * Returns the default subbuf size for the kernel domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t default_get_kernel_channel_subbuf_size(void) > +{ > + return default_kernel_channel_subbuf_size; > +} > + > +/* > + * Returns the default subbuf size for the UST domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +size_t default_get_ust_channel_subbuf_size(void) > +{ > + return default_ust_channel_subbuf_size; > +} > diff --git a/src/common/defaults.h b/src/common/defaults.h > index 0c0b6ac..94a54c1 100644 > --- a/src/common/defaults.h > +++ b/src/common/defaults.h > @@ -109,6 +109,9 @@ > #define DEFAULT_METADATA_SUBBUF_SIZE 4096 > #define DEFAULT_METADATA_SUBBUF_NUM 2 > > +size_t default_get_channel_subbuf_size(void); > +size_t default_get_metadata_subbuf_size(void); > + > /* Kernel has different defaults */ > > /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ > @@ -121,6 +124,8 @@ > /* See lttng-kernel.h enum lttng_kernel_output for channel output */ > #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE > > +size_t default_get_kernel_channel_subbuf_size(void); > + > /* User space defaults */ > > /* Must be a power of 2 */ > @@ -130,6 +135,8 @@ > /* See lttng-ust.h enum lttng_ust_output */ > #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP > > +size_t default_get_ust_channel_subbuf_size(void); > + > /* > * Default timeout value for the sem_timedwait() call. Blocking forever is not > * wanted so a timeout is used to control the data flow and not freeze the From simon.marchi at polymtl.ca Mon Nov 12 14:23:36 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Mon, 12 Nov 2012 14:23:36 -0500 Subject: [lttng-dev] [PATCH v3 1/2] Add default subbuf sizes getter functions Message-ID: <1352748217-21473-1-git-send-email-simon.marchi@polymtl.ca> This patch adds functions to retrieve defaults subbuf sizes. It uses the DEFAULT_*_SUBBUF_SIZE defines from defaults.h but also make sure that the values are at least as big as the page size. The functions are defined as static inline in defaults.h. Signed-off-by: Simon Marchi --- src/common/Makefile.am | 2 +- src/common/defaults.c | 48 ++++++++++++++++++++++++++++++++++++++++ src/common/defaults.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletions(-) create mode 100644 src/common/defaults.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b43b376..f91259c 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ - common.h futex.c futex.h uri.c uri.h + common.h futex.c futex.h uri.c uri.h defaults.c # Consumer library noinst_LTLIBRARIES += libconsumer.la diff --git a/src/common/defaults.c b/src/common/defaults.c new file mode 100644 index 0000000..27eae90 --- /dev/null +++ b/src/common/defaults.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 - Simon Marchi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "defaults.h" + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +size_t default_channel_subbuf_size; +size_t default_metadata_subbuf_size; +size_t default_kernel_channel_subbuf_size; +size_t default_ust_channel_subbuf_size; + +static void __attribute__((constructor)) init_defaults(void) +{ + /* libringbuffer won't accept subbuf sizes smaller than the page size, + * so. If the default subbuf size is smaller, replace it by the page + * size. */ + long page_size = sysconf(_SC_PAGESIZE); + + if (page_size < 0) { + page_size = 0; + } + + default_channel_subbuf_size = max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); + default_metadata_subbuf_size = max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); + default_kernel_channel_subbuf_size = max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); + default_ust_channel_subbuf_size = max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); +} + diff --git a/src/common/defaults.h b/src/common/defaults.h index 0c0b6ac..c1dc204 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -109,6 +109,34 @@ #define DEFAULT_METADATA_SUBBUF_SIZE 4096 #define DEFAULT_METADATA_SUBBUF_NUM 2 +extern size_t default_channel_subbuf_size; +extern size_t default_metadata_subbuf_size; + +/* + * Returns the default subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_channel_subbuf_size(void) +{ + return default_channel_subbuf_size; +} + +/* + * Returns the default metadata subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_metadata_subbuf_size(void) +{ + return default_metadata_subbuf_size; +} + + /* Kernel has different defaults */ /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ @@ -121,6 +149,21 @@ /* See lttng-kernel.h enum lttng_kernel_output for channel output */ #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE +extern size_t default_kernel_channel_subbuf_size; + +/* + * Returns the default subbuf size for the kernel domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_kernel_channel_subbuf_size(void) +{ + return default_kernel_channel_subbuf_size; +} + + /* User space defaults */ /* Must be a power of 2 */ @@ -130,6 +173,20 @@ /* See lttng-ust.h enum lttng_ust_output */ #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP +extern size_t default_ust_channel_subbuf_size; + +/* + * Returns the default subbuf size for the UST domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_ust_channel_subbuf_size(void) +{ + return default_ust_channel_subbuf_size; +} + /* * Default timeout value for the sem_timedwait() call. Blocking forever is not * wanted so a timeout is used to control the data flow and not freeze the -- 1.7.1 From simon.marchi at polymtl.ca Mon Nov 12 14:23:37 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Mon, 12 Nov 2012 14:23:37 -0500 Subject: [lttng-dev] [PATCH v3 2/2] Use the new functions for default subbuf sizes In-Reply-To: <1352748217-21473-1-git-send-email-simon.marchi@polymtl.ca> References: <1352748217-21473-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352748217-21473-2-git-send-email-simon.marchi@polymtl.ca> Use the functions added by the previous commit. All the occurences of the previous defines were replaced. Signed-off-by: Simon Marchi --- src/bin/lttng-sessiond/channel.c | 4 ++-- src/bin/lttng-sessiond/trace-kernel.c | 2 +- src/bin/lttng-sessiond/trace-ust.c | 2 +- src/bin/lttng/commands/enable_channels.c | 6 +++--- src/lib/lttng-ctl/lttng-ctl.c | 4 ++-- tests/tools/Makefile.am | 2 +- tests/tools/test_kernel_data_trace.c | 2 +- tests/tools/test_ust_data_trace.c | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 8b9adfb..a942ff5 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -54,7 +54,7 @@ struct lttng_channel *channel_new_default_attr(int dom) switch (dom) { case LTTNG_DOMAIN_KERNEL: - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_kernel_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -64,7 +64,7 @@ struct lttng_channel *channel_new_default_attr(int dom) case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: case LTTNG_DOMAIN_UST_EXEC_NAME: #endif - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_ust_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 7748b89..4d2870a 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -272,7 +272,7 @@ struct ltt_kernel_metadata *trace_kernel_create_metadata(void) /* Set default attributes */ chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_metadata_subbuf_size(); chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 864a4b0..2dcc7c2 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -311,7 +311,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) /* Set default attributes */ lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + lum->attr.subbuf_size = default_get_metadata_subbuf_size(); lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 1857477..d9a3b02 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -101,9 +101,9 @@ static void usage(FILE *ofp) fprintf(ofp, " --overwrite Flight recorder mode%s\n", DEFAULT_CHANNEL_OVERWRITE ? " (default)" : ""); fprintf(ofp, " --subbuf-size SIZE Subbuffer size in bytes\n"); - fprintf(ofp, " (default: %u, kernel default: %u)\n", - DEFAULT_CHANNEL_SUBBUF_SIZE, - DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); + fprintf(ofp, " (default: %zu, kernel default: %zu)\n", + default_get_channel_subbuf_size(), + default_get_kernel_channel_subbuf_size()); fprintf(ofp, " Needs to be a power of 2 for\n"); fprintf(ofp, " kernel and ust tracers\n"); fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 46338fb..20bb8c6 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1344,7 +1344,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_kernel_channel_subbuf_size(); attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -1358,7 +1358,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_ust_channel_subbuf_size(); attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am index cd7ff32..4fe494c 100644 --- a/tests/tools/Makefile.am +++ b/tests/tools/Makefile.am @@ -27,7 +27,7 @@ test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM) # Kernel trace data unit tests test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE) -test_kernel_data_trace_LDADD = $(SESSIOND_COMM) $(HASHTABLE) +test_kernel_data_trace_LDADD = $(COMMON) $(SESSIOND_COMM) $(HASHTABLE) if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += test_ust_data_trace diff --git a/tests/tools/test_kernel_data_trace.c b/tests/tools/test_kernel_data_trace.c index c49d7ce..1edd20d 100644 --- a/tests/tools/test_kernel_data_trace.c +++ b/tests/tools/test_kernel_data_trace.c @@ -99,7 +99,7 @@ static void create_kernel_metadata(void) assert(kern->metadata->conf->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(kern->metadata->conf->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(kern->metadata->conf->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(kern->metadata->conf->attr.switch_timer_interval diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c index 459520d..69a73b2 100644 --- a/tests/tools/test_ust_data_trace.c +++ b/tests/tools/test_ust_data_trace.c @@ -107,7 +107,7 @@ static void create_ust_metadata(void) assert(metadata->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(metadata->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(metadata->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(metadata->attr.switch_timer_interval -- 1.7.1 From adrien.verge at polymtl.ca Mon Nov 12 14:50:42 2012 From: adrien.verge at polymtl.ca (=?UTF-8?q?Adrien=20Verg=C3=A9?=) Date: Mon, 12 Nov 2012 14:50:42 -0500 Subject: [lttng-dev] [LTTng-ust patch] Added compatibilty for armv7l (Panda Board) Message-ID: <1352749842-3756-1-git-send-email-adrien.verge@polymtl.ca> Signed-off-by: Adrien Verg? --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 91ad8d9..9e94668 100644 --- a/configure.ac +++ b/configure.ac @@ -209,6 +209,7 @@ changequote([,])dnl s390) LIBFORMAT="elf32-s390"; NO_UNALIGNED_ACCESS=1 ;; s390x) LIBFORMAT="elf64-s390"; NO_UNALIGNED_ACCESS=1 ;; armv5) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; + armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; arm) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; mips*) LIBFORMAT=""; NO_UNALIGNED_ACCESS=1;; *) AC_MSG_ERROR([unable to detect library format (unsupported architecture ($host_cpu)?)]) ;; -- 1.7.11.7 From mathieu.desnoyers at efficios.com Mon Nov 12 15:42:01 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 12 Nov 2012 15:42:01 -0500 Subject: [lttng-dev] [LTTng-ust patch] Added compatibilty for armv7l (Panda Board) In-Reply-To: <1352749842-3756-1-git-send-email-adrien.verge@polymtl.ca> References: <1352749842-3756-1-git-send-email-adrien.verge@polymtl.ca> Message-ID: <20121112204201.GA2528@Krystal> The following master branch commit makes this patch unnecessary: commit dca6e79f31143ffc08f8bd5ef832f820fe4546bf Author: Mathieu Desnoyers Date: Mon Nov 12 15:40:15 2012 -0500 Remove LIBFORMAT config declaration, unused Remove leftover from UST 0.x. Not needed anymore. Signed-off-by: Mathieu Desnoyers Thanks, Mathieu * Adrien Verg? (adrien.verge at polymtl.ca) wrote: > Signed-off-by: Adrien Verg? > --- > configure.ac | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/configure.ac b/configure.ac > index 91ad8d9..9e94668 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -209,6 +209,7 @@ changequote([,])dnl > s390) LIBFORMAT="elf32-s390"; NO_UNALIGNED_ACCESS=1 ;; > s390x) LIBFORMAT="elf64-s390"; NO_UNALIGNED_ACCESS=1 ;; > armv5) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > + armv7l) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > arm) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > mips*) LIBFORMAT=""; NO_UNALIGNED_ACCESS=1;; > *) AC_MSG_ERROR([unable to detect library format (unsupported architecture ($host_cpu)?)]) ;; > -- > 1.7.11.7 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 12 15:43:01 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 12 Nov 2012 15:43:01 -0500 Subject: [lttng-dev] [PATCH lttng-ust] Add compilation support for the TileGX architecture. In-Reply-To: <20121109155731.GB8094@Krystal> References: <1352443711-8662-1-git-send-email-simon.marchi@polymtl.ca> <20121109155731.GB8094@Krystal> Message-ID: <20121112204301.GB2528@Krystal> Hi Simon, Please respin this patch on top of the following commit: commit dca6e79f31143ffc08f8bd5ef832f820fe4546bf Author: Mathieu Desnoyers Date: Mon Nov 12 15:40:15 2012 -0500 Remove LIBFORMAT config declaration, unused Remove leftover from UST 0.x. Not needed anymore. Signed-off-by: Mathieu Desnoyers Thanks, Mathieu * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > First detail: please remove dot from subject end of line. > > * Simon Marchi (simon.marchi at polymtl.ca) wrote: > > Signed-off-by: Simon Marchi > > --- > > configure.ac | 1 + > > 1 files changed, 1 insertions(+), 0 deletions(-) > > > > diff --git a/configure.ac b/configure.ac > > index 7f12f23..97a9f65 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -213,6 +213,7 @@ changequote([,])dnl > > armv5) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > > arm) LIBFORMAT="elf32-littlearm"; NO_UNALIGNED_ACCESS=1 ;; > > mips*) LIBFORMAT=""; NO_UNALIGNED_ACCESS=1;; > > + tile) LIBFORMAT="elf64-tilegx-le"; NO_UNALIGNED_ACCESS=1;; > > Not sure how this works, but I think there exists other "tile" flavors > out there besides the tilegx. Will they appear as "tile" from an > autotools point of view and then break when we specify their libformat > as elf64-tilegx-le ? Are there any way to distinguish between flavors ? > Please ask advice to Tilera if needed. > > Thanks, > > Mathieu > > > *) AC_MSG_ERROR([unable to detect library format (unsupported architecture ($host_cpu)?)]) ;; > > esac > > AC_SUBST(LIBFORMAT) > > -- > > 1.7.1 > > > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Mon Nov 12 15:54:43 2012 From: dgoulet at efficios.com (David Goulet) Date: Mon, 12 Nov 2012 15:54:43 -0500 Subject: [lttng-dev] [PATCH v3 1/2] Add default subbuf sizes getter functions In-Reply-To: <1352748217-21473-1-git-send-email-simon.marchi@polymtl.ca> References: <1352748217-21473-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <50A16213.50109@efficios.com> Simon Marchi: > This patch adds functions to retrieve defaults subbuf sizes. It uses the > DEFAULT_*_SUBBUF_SIZE defines from defaults.h but also make sure that the > values are at least as big as the page size. > > The functions are defined as static inline in defaults.h. > > Signed-off-by: Simon Marchi > --- > src/common/Makefile.am | 2 +- > src/common/defaults.c | 48 ++++++++++++++++++++++++++++++++++++++++ > src/common/defaults.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 106 insertions(+), 1 deletions(-) > create mode 100644 src/common/defaults.c > > diff --git a/src/common/Makefile.am b/src/common/Makefile.am > index b43b376..f91259c 100644 > --- a/src/common/Makefile.am > +++ b/src/common/Makefile.am > @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ > noinst_LTLIBRARIES = libcommon.la > > libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ > - common.h futex.c futex.h uri.c uri.h > + common.h futex.c futex.h uri.c uri.h defaults.c > > # Consumer library > noinst_LTLIBRARIES += libconsumer.la > diff --git a/src/common/defaults.c b/src/common/defaults.c > new file mode 100644 > index 0000000..27eae90 > --- /dev/null > +++ b/src/common/defaults.c > @@ -0,0 +1,48 @@ > +/* > + * Copyright (C) 2012 - Simon Marchi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License, version 2 only, > + * as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include > +#include > + > +#include "defaults.h" > + > +#ifndef max > +#define max(a, b) ((a) > (b) ? (a) : (b)) > +#endif This should go in src/common/macros.h and include the header since this could be reused at some point in the project without linking with libcommon. > + > +size_t default_channel_subbuf_size; > +size_t default_metadata_subbuf_size; > +size_t default_kernel_channel_subbuf_size; > +size_t default_ust_channel_subbuf_size; > + > +static void __attribute__((constructor)) init_defaults(void) > +{ > + /* libringbuffer won't accept subbuf sizes smaller than the page size, > + * so. If the default subbuf size is smaller, replace it by the page > + * size. */ > + long page_size = sysconf(_SC_PAGESIZE); > + Useless tab. > + if (page_size < 0) { > + page_size = 0; > + } > + > + default_channel_subbuf_size = max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); > + default_metadata_subbuf_size = max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); > + default_kernel_channel_subbuf_size = max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); > + default_ust_channel_subbuf_size = max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); Please fit the code on 80 characters. If it's a pain for (probably because you are using emacs :P:P #endlesswar), let me know, I'll do it before merging. > +} > + > diff --git a/src/common/defaults.h b/src/common/defaults.h > index 0c0b6ac..c1dc204 100644 > --- a/src/common/defaults.h > +++ b/src/common/defaults.h > @@ -109,6 +109,34 @@ > #define DEFAULT_METADATA_SUBBUF_SIZE 4096 > #define DEFAULT_METADATA_SUBBUF_NUM 2 > > +extern size_t default_channel_subbuf_size; > +extern size_t default_metadata_subbuf_size; As a matter of "code file standard", can you please declare first #defines, then variables and functions. So here, just put the externs at the end of the header followed by the function declaration. To your defense, this was not in CodingStyle so I'll add this! :) Thanks a lot! David > + > +/* > + * Returns the default subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_channel_subbuf_size(void) > +{ > + return default_channel_subbuf_size; > +} > + > +/* > + * Returns the default metadata subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_metadata_subbuf_size(void) > +{ > + return default_metadata_subbuf_size; > +} > + > + > /* Kernel has different defaults */ > > /* DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE must always be a power of 2 */ > @@ -121,6 +149,21 @@ > /* See lttng-kernel.h enum lttng_kernel_output for channel output */ > #define DEFAULT_KERNEL_CHANNEL_OUTPUT LTTNG_EVENT_SPLICE > > +extern size_t default_kernel_channel_subbuf_size; > + > +/* > + * Returns the default subbuf size for the kernel domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_kernel_channel_subbuf_size(void) > +{ > + return default_kernel_channel_subbuf_size; > +} > + > + > /* User space defaults */ > > /* Must be a power of 2 */ > @@ -130,6 +173,20 @@ > /* See lttng-ust.h enum lttng_ust_output */ > #define DEFAULT_UST_CHANNEL_OUTPUT LTTNG_EVENT_MMAP > > +extern size_t default_ust_channel_subbuf_size; > + > +/* > + * Returns the default subbuf size for the UST domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_ust_channel_subbuf_size(void) > +{ > + return default_ust_channel_subbuf_size; > +} > + > /* > * Default timeout value for the sem_timedwait() call. Blocking forever is not > * wanted so a timeout is used to control the data flow and not freeze the From matthew.khouzam at ericsson.com Tue Nov 13 11:38:43 2012 From: matthew.khouzam at ericsson.com (Matthew Khouzam) Date: Tue, 13 Nov 2012 11:38:43 -0500 Subject: [lttng-dev] Measure network usage In-Reply-To: <509CF3DC.7010700@cs.umu.se> References: <509CF3DC.7010700@cs.umu.se> Message-ID: <50A27793.4000800@ericsson.com> Hi, I know some research is being done in this field, I am bumping so the concerned party can post his work. On 12-11-09 07:15 AM, Luis wrote: > Hello! > > I would like to know how can I measure the network usage of an > application (when and during how much time) by using LTTng software! > > Thank you, > Luis > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From simon.marchi at polymtl.ca Tue Nov 13 13:54:54 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Tue, 13 Nov 2012 13:54:54 -0500 Subject: [lttng-dev] [PATCH 1/3] Add max() and min() macro in common Message-ID: <1352832896-30360-1-git-send-email-simon.marchi@polymtl.ca> Signed-off-by: Simon Marchi --- src/common/macros.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/src/common/macros.h b/src/common/macros.h index 8185c85..81f901c 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -52,4 +52,12 @@ #define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) #endif +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #endif /* _MACROS_H */ -- 1.7.1 From simon.marchi at polymtl.ca Tue Nov 13 13:54:55 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Tue, 13 Nov 2012 13:54:55 -0500 Subject: [lttng-dev] [PATCH 2/3] Add default subbuf sizes getter functions In-Reply-To: <1352832896-30360-1-git-send-email-simon.marchi@polymtl.ca> References: <1352832896-30360-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352832896-30360-2-git-send-email-simon.marchi@polymtl.ca> This patch adds functions to retrieve defaults subbuf sizes. It uses the DEFAULT_*_SUBBUF_SIZE defines from defaults.h but also make sure that the values are at least as big as the page size. The functions are defined as static inline in defaults.h. Signed-off-by: Simon Marchi --- src/common/Makefile.am | 2 +- src/common/defaults.c | 50 +++++++++++++++++++++++++++++++++++++++++++ src/common/defaults.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletions(-) create mode 100644 src/common/defaults.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b43b376..f91259c 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ - common.h futex.c futex.h uri.c uri.h + common.h futex.c futex.h uri.c uri.h defaults.c # Consumer library noinst_LTLIBRARIES += libconsumer.la diff --git a/src/common/defaults.c b/src/common/defaults.c new file mode 100644 index 0000000..ee6b777 --- /dev/null +++ b/src/common/defaults.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 - Simon Marchi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "defaults.h" + +#include "macros.h" + +size_t default_channel_subbuf_size; +size_t default_metadata_subbuf_size; +size_t default_kernel_channel_subbuf_size; +size_t default_ust_channel_subbuf_size; + +static void __attribute__((constructor)) init_defaults(void) +{ + /* libringbuffer won't accept subbuf sizes smaller than the page size, + * so. If the default subbuf size is smaller, replace it by the page + * size. */ + long page_size = sysconf(_SC_PAGESIZE); + + if (page_size < 0) { + page_size = 0; + } + + default_channel_subbuf_size = + max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); + default_metadata_subbuf_size = + max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); + default_kernel_channel_subbuf_size = + max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); + default_ust_channel_subbuf_size = + max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); +} + diff --git a/src/common/defaults.h b/src/common/defaults.h index 0c0b6ac..efcd792 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -160,4 +160,59 @@ #define DEFAULT_APP_SOCKET_RW_TIMEOUT 5 /* sec */ #define DEFAULT_APP_SOCKET_TIMEOUT_ENV "LTTNG_APP_SOCKET_TIMEOUT" + +extern size_t default_channel_subbuf_size; +extern size_t default_metadata_subbuf_size; +extern size_t default_ust_channel_subbuf_size; +extern size_t default_kernel_channel_subbuf_size; + + +/* + * Returns the default subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_channel_subbuf_size(void) +{ + return default_channel_subbuf_size; +} + +/* + * Returns the default metadata subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_metadata_subbuf_size(void) +{ + return default_metadata_subbuf_size; +} + +/* + * Returns the default subbuf size for the kernel domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_kernel_channel_subbuf_size(void) +{ + return default_kernel_channel_subbuf_size; +} + +/* + * Returns the default subbuf size for the UST domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_ust_channel_subbuf_size(void) +{ + return default_ust_channel_subbuf_size; +} + #endif /* _DEFAULTS_H */ -- 1.7.1 From simon.marchi at polymtl.ca Tue Nov 13 13:54:56 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Tue, 13 Nov 2012 13:54:56 -0500 Subject: [lttng-dev] [PATCH 3/3] Use the new functions for default subbuf sizes In-Reply-To: <1352832896-30360-1-git-send-email-simon.marchi@polymtl.ca> References: <1352832896-30360-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352832896-30360-3-git-send-email-simon.marchi@polymtl.ca> Use the functions added by the previous commit. All the occurences of the previous defines were replaced. Signed-off-by: Simon Marchi --- src/bin/lttng-sessiond/channel.c | 4 ++-- src/bin/lttng-sessiond/trace-kernel.c | 2 +- src/bin/lttng-sessiond/trace-ust.c | 2 +- src/bin/lttng/commands/enable_channels.c | 6 +++--- src/lib/lttng-ctl/lttng-ctl.c | 4 ++-- tests/tools/Makefile.am | 2 +- tests/tools/test_kernel_data_trace.c | 2 +- tests/tools/test_ust_data_trace.c | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 8b9adfb..a942ff5 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -54,7 +54,7 @@ struct lttng_channel *channel_new_default_attr(int dom) switch (dom) { case LTTNG_DOMAIN_KERNEL: - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_kernel_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -64,7 +64,7 @@ struct lttng_channel *channel_new_default_attr(int dom) case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: case LTTNG_DOMAIN_UST_EXEC_NAME: #endif - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_ust_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 7748b89..4d2870a 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -272,7 +272,7 @@ struct ltt_kernel_metadata *trace_kernel_create_metadata(void) /* Set default attributes */ chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_metadata_subbuf_size(); chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 864a4b0..2dcc7c2 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -311,7 +311,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) /* Set default attributes */ lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + lum->attr.subbuf_size = default_get_metadata_subbuf_size(); lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 1857477..d9a3b02 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -101,9 +101,9 @@ static void usage(FILE *ofp) fprintf(ofp, " --overwrite Flight recorder mode%s\n", DEFAULT_CHANNEL_OVERWRITE ? " (default)" : ""); fprintf(ofp, " --subbuf-size SIZE Subbuffer size in bytes\n"); - fprintf(ofp, " (default: %u, kernel default: %u)\n", - DEFAULT_CHANNEL_SUBBUF_SIZE, - DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); + fprintf(ofp, " (default: %zu, kernel default: %zu)\n", + default_get_channel_subbuf_size(), + default_get_kernel_channel_subbuf_size()); fprintf(ofp, " Needs to be a power of 2 for\n"); fprintf(ofp, " kernel and ust tracers\n"); fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 46338fb..20bb8c6 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1344,7 +1344,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_kernel_channel_subbuf_size(); attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -1358,7 +1358,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_ust_channel_subbuf_size(); attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am index cd7ff32..4fe494c 100644 --- a/tests/tools/Makefile.am +++ b/tests/tools/Makefile.am @@ -27,7 +27,7 @@ test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM) # Kernel trace data unit tests test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE) -test_kernel_data_trace_LDADD = $(SESSIOND_COMM) $(HASHTABLE) +test_kernel_data_trace_LDADD = $(COMMON) $(SESSIOND_COMM) $(HASHTABLE) if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += test_ust_data_trace diff --git a/tests/tools/test_kernel_data_trace.c b/tests/tools/test_kernel_data_trace.c index c49d7ce..1edd20d 100644 --- a/tests/tools/test_kernel_data_trace.c +++ b/tests/tools/test_kernel_data_trace.c @@ -99,7 +99,7 @@ static void create_kernel_metadata(void) assert(kern->metadata->conf->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(kern->metadata->conf->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(kern->metadata->conf->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(kern->metadata->conf->attr.switch_timer_interval diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c index 459520d..69a73b2 100644 --- a/tests/tools/test_ust_data_trace.c +++ b/tests/tools/test_ust_data_trace.c @@ -107,7 +107,7 @@ static void create_ust_metadata(void) assert(metadata->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(metadata->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(metadata->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(metadata->attr.switch_timer_interval -- 1.7.1 From mathieu.desnoyers at efficios.com Tue Nov 13 13:59:42 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 13 Nov 2012 13:59:42 -0500 Subject: [lttng-dev] [PATCH 2/3] Add default subbuf sizes getter functions In-Reply-To: <1352832896-30360-2-git-send-email-simon.marchi@polymtl.ca> References: <1352832896-30360-1-git-send-email-simon.marchi@polymtl.ca> <1352832896-30360-2-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121113185942.GA25524@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > This patch adds functions to retrieve defaults subbuf sizes. It uses the > DEFAULT_*_SUBBUF_SIZE defines from defaults.h but also make sure that the > values are at least as big as the page size. > > The functions are defined as static inline in defaults.h. Please prefix your subject with e.g.: [PATCH lttng-tools x/y] more below, > > Signed-off-by: Simon Marchi > --- > src/common/Makefile.am | 2 +- > src/common/defaults.c | 50 +++++++++++++++++++++++++++++++++++++++++++ > src/common/defaults.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 106 insertions(+), 1 deletions(-) > create mode 100644 src/common/defaults.c > > diff --git a/src/common/Makefile.am b/src/common/Makefile.am > index b43b376..f91259c 100644 > --- a/src/common/Makefile.am > +++ b/src/common/Makefile.am > @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ > noinst_LTLIBRARIES = libcommon.la > > libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ > - common.h futex.c futex.h uri.c uri.h > + common.h futex.c futex.h uri.c uri.h defaults.c > > # Consumer library > noinst_LTLIBRARIES += libconsumer.la > diff --git a/src/common/defaults.c b/src/common/defaults.c > new file mode 100644 > index 0000000..ee6b777 > --- /dev/null > +++ b/src/common/defaults.c > @@ -0,0 +1,50 @@ > +/* > + * Copyright (C) 2012 - Simon Marchi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License, version 2 only, > + * as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + */ > + > +#include > +#include > + > +#include "defaults.h" > + > +#include "macros.h" > + > +size_t default_channel_subbuf_size; > +size_t default_metadata_subbuf_size; > +size_t default_kernel_channel_subbuf_size; > +size_t default_ust_channel_subbuf_size; > + > +static void __attribute__((constructor)) init_defaults(void) > +{ > + /* libringbuffer won't accept subbuf sizes smaller than the page size, > + * so. If the default subbuf size is smaller, replace it by the page > + * size. */ > + long page_size = sysconf(_SC_PAGESIZE); > + > + if (page_size < 0) { > + page_size = 0; > + } > + > + default_channel_subbuf_size = > + max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); > + default_metadata_subbuf_size = > + max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); > + default_kernel_channel_subbuf_size = > + max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); > + default_ust_channel_subbuf_size = > + max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); spaces -> tabs Thanks, Mathieu > +} > + > diff --git a/src/common/defaults.h b/src/common/defaults.h > index 0c0b6ac..efcd792 100644 > --- a/src/common/defaults.h > +++ b/src/common/defaults.h > @@ -160,4 +160,59 @@ > #define DEFAULT_APP_SOCKET_RW_TIMEOUT 5 /* sec */ > #define DEFAULT_APP_SOCKET_TIMEOUT_ENV "LTTNG_APP_SOCKET_TIMEOUT" > > + > +extern size_t default_channel_subbuf_size; > +extern size_t default_metadata_subbuf_size; > +extern size_t default_ust_channel_subbuf_size; > +extern size_t default_kernel_channel_subbuf_size; > + > + > +/* > + * Returns the default subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_channel_subbuf_size(void) > +{ > + return default_channel_subbuf_size; > +} > + > +/* > + * Returns the default metadata subbuf size. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_metadata_subbuf_size(void) > +{ > + return default_metadata_subbuf_size; > +} > + > +/* > + * Returns the default subbuf size for the kernel domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_kernel_channel_subbuf_size(void) > +{ > + return default_kernel_channel_subbuf_size; > +} > + > +/* > + * Returns the default subbuf size for the UST domain. > + * > + * This function depends on a value that is set at constructor time, so it is > + * unsafe to call it from another constructor. > + */ > +static inline > +size_t default_get_ust_channel_subbuf_size(void) > +{ > + return default_ust_channel_subbuf_size; > +} > + > #endif /* _DEFAULTS_H */ > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Tue Nov 13 14:00:30 2012 From: dgoulet at efficios.com (David Goulet) Date: Tue, 13 Nov 2012 14:00:30 -0500 Subject: [lttng-dev] [RELEASE] LTTng-tools 2.1.0-rc7 Message-ID: <50A298CE.30301@efficios.com> Greetings everyone (including LTTng elves), The lttng-tools project provides a session daemon (lttng-sessiond) that acts as a tracing registry, the "lttng" command line for tracing control, a lttng-ctl library for tracing control and a lttng-relayd for network streaming. Please note that this is the release candidate 7 and we are currently fixing the last bugs and updating the documentation for the stable version. I think we might have two or three other RCs before the official stable in a few days! Here is the Changelog. This is mostly fixes from the bug tracker and other encountered issues during that time. 2012-11-13 lttng-tools 2.1.0-rc7 * Fix: Add pointer check when freeing poll events * Fix: FD leak on thread error * Fix: Wrong fd used by kernel_wait_quiescent * Support new lttng-ust error code * Fix: Don't set filter if enable event fails * Fix: Wrong data port when listing session * Fix: Enable event after start command * Fix: Teardown of thread_manage_clients on failure of listen/create_poll * Add a timeout to UST application socket * Fix: Consumerd error socket connect race * Fix: Set CLOEXEC flag on every created sockets * Remove consumer poll timeout in data thread * Fix: RCU hash table seed * Fix: Do not install health tests helper libraries * Fix: Create default channel on add-context if none * Support new liblttng-ust-ctl error code * Fix: Add EPIPE error handling on buffer splice * Fix: Channel creation error return code was not set * Fix: Wrong poll events on UST application socket * Fix: Remove dependency to urcu-cds in tools tests * Fix: Missing librt dependency in configure check for lttng-ust-ctl * Fix: Don't append datetime to default session name * Fix: Deny session creation name 'auto' * Fix: Add space for stream name CPU number * Fix: Add output option to enable-channel command Please feel free to email the list about any questions/comments concerning this release. Using it is testing it! :) Project website: http://lttng.org/lttng2.0 Download link: http://lttng.org/files/lttng-tools/lttng-tools-2.1.0-rc7.tar.bz2 (for the PGP signature, same file with .asc appended) Cheers! David From simon.marchi at polymtl.ca Tue Nov 13 14:28:41 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Tue, 13 Nov 2012 14:28:41 -0500 Subject: [lttng-dev] [PATCH lttng-tools 1/3] Add max() and min() macro in common Message-ID: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> Signed-off-by: Simon Marchi --- src/common/macros.h | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/src/common/macros.h b/src/common/macros.h index 8185c85..81f901c 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -52,4 +52,12 @@ #define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) #endif +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + #endif /* _MACROS_H */ -- 1.7.1 From simon.marchi at polymtl.ca Tue Nov 13 14:28:42 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Tue, 13 Nov 2012 14:28:42 -0500 Subject: [lttng-dev] [PATCH lttng-tools 2/3] Add default subbuf sizes getter functions In-Reply-To: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> References: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352834923-662-2-git-send-email-simon.marchi@polymtl.ca> This patch adds functions to retrieve defaults subbuf sizes. It uses the DEFAULT_*_SUBBUF_SIZE defines from defaults.h but also make sure that the values are at least as big as the page size. The functions are defined as static inline in defaults.h. Signed-off-by: Simon Marchi --- src/common/Makefile.am | 2 +- src/common/defaults.c | 50 +++++++++++++++++++++++++++++++++++++++++++ src/common/defaults.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletions(-) create mode 100644 src/common/defaults.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b43b376..f91259c 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,7 +12,7 @@ noinst_HEADERS = lttng-kernel.h defaults.h macros.h error.h futex.h \ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.c runas.h \ - common.h futex.c futex.h uri.c uri.h + common.h futex.c futex.h uri.c uri.h defaults.c # Consumer library noinst_LTLIBRARIES += libconsumer.la diff --git a/src/common/defaults.c b/src/common/defaults.c new file mode 100644 index 0000000..a72ef9e --- /dev/null +++ b/src/common/defaults.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 - Simon Marchi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "defaults.h" + +#include "macros.h" + +size_t default_channel_subbuf_size; +size_t default_metadata_subbuf_size; +size_t default_kernel_channel_subbuf_size; +size_t default_ust_channel_subbuf_size; + +static void __attribute__((constructor)) init_defaults(void) +{ + /* libringbuffer won't accept subbuf sizes smaller than the page size, + * so. If the default subbuf size is smaller, replace it by the page + * size. */ + long page_size = sysconf(_SC_PAGESIZE); + + if (page_size < 0) { + page_size = 0; + } + + default_channel_subbuf_size = + max(DEFAULT_CHANNEL_SUBBUF_SIZE, page_size); + default_metadata_subbuf_size = + max(DEFAULT_METADATA_SUBBUF_SIZE, page_size); + default_kernel_channel_subbuf_size = + max(DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE, page_size); + default_ust_channel_subbuf_size = + max(DEFAULT_UST_CHANNEL_SUBBUF_SIZE, page_size); +} + diff --git a/src/common/defaults.h b/src/common/defaults.h index 0c0b6ac..efcd792 100644 --- a/src/common/defaults.h +++ b/src/common/defaults.h @@ -160,4 +160,59 @@ #define DEFAULT_APP_SOCKET_RW_TIMEOUT 5 /* sec */ #define DEFAULT_APP_SOCKET_TIMEOUT_ENV "LTTNG_APP_SOCKET_TIMEOUT" + +extern size_t default_channel_subbuf_size; +extern size_t default_metadata_subbuf_size; +extern size_t default_ust_channel_subbuf_size; +extern size_t default_kernel_channel_subbuf_size; + + +/* + * Returns the default subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_channel_subbuf_size(void) +{ + return default_channel_subbuf_size; +} + +/* + * Returns the default metadata subbuf size. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_metadata_subbuf_size(void) +{ + return default_metadata_subbuf_size; +} + +/* + * Returns the default subbuf size for the kernel domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_kernel_channel_subbuf_size(void) +{ + return default_kernel_channel_subbuf_size; +} + +/* + * Returns the default subbuf size for the UST domain. + * + * This function depends on a value that is set at constructor time, so it is + * unsafe to call it from another constructor. + */ +static inline +size_t default_get_ust_channel_subbuf_size(void) +{ + return default_ust_channel_subbuf_size; +} + #endif /* _DEFAULTS_H */ -- 1.7.1 From simon.marchi at polymtl.ca Tue Nov 13 14:28:43 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Tue, 13 Nov 2012 14:28:43 -0500 Subject: [lttng-dev] [PATCH lttng-tools 3/3] Use the new functions for default subbuf sizes In-Reply-To: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> References: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1352834923-662-3-git-send-email-simon.marchi@polymtl.ca> Use the functions added by the previous commit. All the occurences of the previous defines were replaced. Signed-off-by: Simon Marchi --- src/bin/lttng-sessiond/channel.c | 5 +++-- src/bin/lttng-sessiond/trace-kernel.c | 2 +- src/bin/lttng-sessiond/trace-ust.c | 2 +- src/bin/lttng/commands/enable_channels.c | 6 +++--- src/lib/lttng-ctl/lttng-ctl.c | 4 ++-- tests/tools/Makefile.am | 2 +- tests/tools/test_kernel_data_trace.c | 2 +- tests/tools/test_ust_data_trace.c | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/bin/lttng-sessiond/channel.c b/src/bin/lttng-sessiond/channel.c index 8b9adfb..d07e1d9 100644 --- a/src/bin/lttng-sessiond/channel.c +++ b/src/bin/lttng-sessiond/channel.c @@ -54,7 +54,8 @@ struct lttng_channel *channel_new_default_attr(int dom) switch (dom) { case LTTNG_DOMAIN_KERNEL: - chan->attr.subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = + default_get_kernel_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -64,7 +65,7 @@ struct lttng_channel *channel_new_default_attr(int dom) case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: case LTTNG_DOMAIN_UST_EXEC_NAME: #endif - chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_ust_channel_subbuf_size(); chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; chan->attr.output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 7748b89..4d2870a 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -272,7 +272,7 @@ struct ltt_kernel_metadata *trace_kernel_create_metadata(void) /* Set default attributes */ chan->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - chan->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + chan->attr.subbuf_size = default_get_metadata_subbuf_size(); chan->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; chan->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; chan->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 864a4b0..2dcc7c2 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -311,7 +311,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path) /* Set default attributes */ lum->attr.overwrite = DEFAULT_CHANNEL_OVERWRITE; - lum->attr.subbuf_size = DEFAULT_METADATA_SUBBUF_SIZE; + lum->attr.subbuf_size = default_get_metadata_subbuf_size(); lum->attr.num_subbuf = DEFAULT_METADATA_SUBBUF_NUM; lum->attr.switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; lum->attr.read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; diff --git a/src/bin/lttng/commands/enable_channels.c b/src/bin/lttng/commands/enable_channels.c index 1857477..d9a3b02 100644 --- a/src/bin/lttng/commands/enable_channels.c +++ b/src/bin/lttng/commands/enable_channels.c @@ -101,9 +101,9 @@ static void usage(FILE *ofp) fprintf(ofp, " --overwrite Flight recorder mode%s\n", DEFAULT_CHANNEL_OVERWRITE ? " (default)" : ""); fprintf(ofp, " --subbuf-size SIZE Subbuffer size in bytes\n"); - fprintf(ofp, " (default: %u, kernel default: %u)\n", - DEFAULT_CHANNEL_SUBBUF_SIZE, - DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE); + fprintf(ofp, " (default: %zu, kernel default: %zu)\n", + default_get_channel_subbuf_size(), + default_get_kernel_channel_subbuf_size()); fprintf(ofp, " Needs to be a power of 2 for\n"); fprintf(ofp, " kernel and ust tracers\n"); fprintf(ofp, " --num-subbuf NUM Number of subbufers\n"); diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 46338fb..20bb8c6 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1344,7 +1344,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_KERNEL_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_kernel_channel_subbuf_size(); attr->num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_KERNEL_CHANNEL_OUTPUT; break; @@ -1358,7 +1358,7 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain, attr->switch_timer_interval = DEFAULT_CHANNEL_SWITCH_TIMER; attr->read_timer_interval = DEFAULT_CHANNEL_READ_TIMER; - attr->subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE; + attr->subbuf_size = default_get_ust_channel_subbuf_size(); attr->num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM; attr->output = DEFAULT_UST_CHANNEL_OUTPUT; break; diff --git a/tests/tools/Makefile.am b/tests/tools/Makefile.am index cd7ff32..4fe494c 100644 --- a/tests/tools/Makefile.am +++ b/tests/tools/Makefile.am @@ -27,7 +27,7 @@ test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM) # Kernel trace data unit tests test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE) -test_kernel_data_trace_LDADD = $(SESSIOND_COMM) $(HASHTABLE) +test_kernel_data_trace_LDADD = $(COMMON) $(SESSIOND_COMM) $(HASHTABLE) if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += test_ust_data_trace diff --git a/tests/tools/test_kernel_data_trace.c b/tests/tools/test_kernel_data_trace.c index c49d7ce..1edd20d 100644 --- a/tests/tools/test_kernel_data_trace.c +++ b/tests/tools/test_kernel_data_trace.c @@ -99,7 +99,7 @@ static void create_kernel_metadata(void) assert(kern->metadata->conf->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(kern->metadata->conf->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(kern->metadata->conf->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(kern->metadata->conf->attr.switch_timer_interval diff --git a/tests/tools/test_ust_data_trace.c b/tests/tools/test_ust_data_trace.c index 459520d..69a73b2 100644 --- a/tests/tools/test_ust_data_trace.c +++ b/tests/tools/test_ust_data_trace.c @@ -107,7 +107,7 @@ static void create_ust_metadata(void) assert(metadata->attr.overwrite == DEFAULT_CHANNEL_OVERWRITE); assert(metadata->attr.subbuf_size - == DEFAULT_METADATA_SUBBUF_SIZE); + == default_get_metadata_subbuf_size()); assert(metadata->attr.num_subbuf == DEFAULT_METADATA_SUBBUF_NUM); assert(metadata->attr.switch_timer_interval -- 1.7.1 From dgoulet at efficios.com Tue Nov 13 14:50:43 2012 From: dgoulet at efficios.com (David Goulet) Date: Tue, 13 Nov 2012 14:50:43 -0500 Subject: [lttng-dev] [PATCH lttng-tools 1/3] Add max() and min() macro in common In-Reply-To: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> References: <1352834923-662-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <50A2A493.4080503@efficios.com> All three patches are now upstream! Cheers David Simon Marchi: > Signed-off-by: Simon Marchi > --- > src/common/macros.h | 8 ++++++++ > 1 files changed, 8 insertions(+), 0 deletions(-) > > diff --git a/src/common/macros.h b/src/common/macros.h > index 8185c85..81f901c 100644 > --- a/src/common/macros.h > +++ b/src/common/macros.h > @@ -52,4 +52,12 @@ > #define ARRAY_SIZE(array) (sizeof(array) / (sizeof((array)[0]))) > #endif > > +#ifndef max > +#define max(a, b) ((a) > (b) ? (a) : (b)) > +#endif > + > +#ifndef min > +#define min(a, b) ((a) < (b) ? (a) : (b)) > +#endif > + > #endif /* _MACROS_H */ From David.OShea at quantum.com Wed Nov 14 00:04:01 2012 From: David.OShea at quantum.com (David OShea) Date: Wed, 14 Nov 2012 05:04:01 +0000 Subject: [lttng-dev] Broken links on lttng.org Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F86D7E@ZURMSG1.QUANTUM.com> Hi all, I noticed that a number of things were broken on the website in the last few weeks: 1. At http://lttng.org/documentation, the five man page links at the top are broken (return "Page not found"). I haven't tried other links on that page. 2. http://lttng.org/tracingwiki/index.php/ is now broken ("Page not found"). I can't remember what used to be in that wiki, or how I found it, but I seem to remember it being useful :) Thanks in advance, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From Paul_Woegerer at mentor.com Wed Nov 14 04:55:10 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Wed, 14 Nov 2012 10:55:10 +0100 Subject: [lttng-dev] [PATCH lttng-modules] Additional kernel probes In-Reply-To: <20121112142928.GB23655@Krystal> References: <50A0FB68.5060100@mentor.com> <20121112142928.GB23655@Krystal> Message-ID: <50A36A7E.3000203@mentor.com> On 11/12/2012 03:29 PM, Mathieu Desnoyers wrote: > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: >> The probes are verified to compile against all kernel versions from >> 3.0 to 3.6 (3.7-rc5 also works). > > LTTng-modules states that 2.6.38 and 2.6.39 are supported too. Could you > test those against these two kernel versions too ? Added support down to 2.6.38 (couple more ifdefs in net.h) See Subject: [PATCH 2/3] Add ifdefs to net probe to support Linux 2.6.39 > lttng-modules TP_fast_assign() section should not have semicolumn at the > end of lines, e.g.: > > TP_fast_assign( > tp_strcpy(name, codec->name) > tp_assign(id, codec->id) > tp_assign(reg, reg) > tp_assign(val, val) > ) Fixed for all probes. See Subject: [PATCH 3/3] Remove semicolons in TP_fast_assign blocks. And now the updated patch series ... >From bb32fa6dd5e569d110b0f60ba705a398265a7617 Mon Sep 17 00:00:00 2001 From: Paul Woegerer Date: Mon, 12 Nov 2012 14:07:12 +0100 Subject: [PATCH 1/3] Add kernel probes for asoc, ext3, gpio, jbd, jbd2, kmem, lock, module, napi, net, power, regulator, scsi, skb, sock, udp, vmscan. --- instrumentation/events/lttng-module/asoc.h | 340 ++++++ instrumentation/events/lttng-module/ext3.h | 870 +++++++++++++++ instrumentation/events/lttng-module/gpio.h | 56 + instrumentation/events/lttng-module/jbd.h | 243 +++++ instrumentation/events/lttng-module/jbd2.h | 238 ++++ instrumentation/events/lttng-module/kmem.h | 304 ++++++ instrumentation/events/lttng-module/lock.h | 86 ++ instrumentation/events/lttng-module/module.h | 134 +++ instrumentation/events/lttng-module/napi.h | 38 + instrumentation/events/lttng-module/net.h | 84 ++ instrumentation/events/lttng-module/power.h | 240 ++++ instrumentation/events/lttng-module/regulator.h | 141 +++ instrumentation/events/lttng-module/scsi.h | 369 +++++++ instrumentation/events/lttng-module/skb.h | 75 ++ instrumentation/events/lttng-module/sock.h | 68 ++ instrumentation/events/lttng-module/udp.h | 32 + instrumentation/events/lttng-module/vmscan.h | 499 +++++++++ instrumentation/events/mainline/asoc.h | 330 ++++++ instrumentation/events/mainline/ext3.h | 864 +++++++++++++++ instrumentation/events/mainline/fs_ext3.h | 1323 +++++++++++++++++++++++ instrumentation/events/mainline/gpio.h | 56 + instrumentation/events/mainline/jbd.h | 203 ++++ instrumentation/events/mainline/jbd2.h | 235 ++++ instrumentation/events/mainline/kmem.h | 308 ++++++ instrumentation/events/mainline/lock.h | 86 ++ instrumentation/events/mainline/module.h | 131 +++ instrumentation/events/mainline/napi.h | 38 + instrumentation/events/mainline/net.h | 84 ++ instrumentation/events/mainline/power.h | 240 ++++ instrumentation/events/mainline/regulator.h | 141 +++ instrumentation/events/mainline/scsi.h | 365 +++++++ instrumentation/events/mainline/skb.h | 75 ++ instrumentation/events/mainline/sock.h | 68 ++ instrumentation/events/mainline/udp.h | 32 + instrumentation/events/mainline/vmscan.h | 477 ++++++++ probes/Makefile | 72 ++ probes/lttng-probe-asoc.c | 45 + probes/lttng-probe-ext3.c | 56 + probes/lttng-probe-gpio.c | 43 + probes/lttng-probe-jbd.c | 44 + probes/lttng-probe-jbd2.c | 43 + probes/lttng-probe-kmem.c | 43 + probes/lttng-probe-lock.c | 43 + probes/lttng-probe-module.c | 43 + probes/lttng-probe-napi.c | 43 + probes/lttng-probe-net.c | 43 + probes/lttng-probe-power.c | 43 + probes/lttng-probe-regulator.c | 43 + probes/lttng-probe-scsi.c | 44 + probes/lttng-probe-skb.c | 43 + probes/lttng-probe-sock.c | 43 + probes/lttng-probe-udp.c | 43 + probes/lttng-probe-vmscan.c | 48 + 53 files changed, 9698 insertions(+) create mode 100644 instrumentation/events/lttng-module/asoc.h create mode 100644 instrumentation/events/lttng-module/ext3.h create mode 100644 instrumentation/events/lttng-module/gpio.h create mode 100644 instrumentation/events/lttng-module/jbd.h create mode 100644 instrumentation/events/lttng-module/jbd2.h create mode 100644 instrumentation/events/lttng-module/kmem.h create mode 100644 instrumentation/events/lttng-module/lock.h create mode 100644 instrumentation/events/lttng-module/module.h create mode 100644 instrumentation/events/lttng-module/napi.h create mode 100644 instrumentation/events/lttng-module/net.h create mode 100644 instrumentation/events/lttng-module/power.h create mode 100644 instrumentation/events/lttng-module/regulator.h create mode 100644 instrumentation/events/lttng-module/scsi.h create mode 100644 instrumentation/events/lttng-module/skb.h create mode 100644 instrumentation/events/lttng-module/sock.h create mode 100644 instrumentation/events/lttng-module/udp.h create mode 100644 instrumentation/events/lttng-module/vmscan.h create mode 100644 instrumentation/events/mainline/asoc.h create mode 100644 instrumentation/events/mainline/ext3.h create mode 100644 instrumentation/events/mainline/fs_ext3.h create mode 100644 instrumentation/events/mainline/gpio.h create mode 100644 instrumentation/events/mainline/jbd.h create mode 100644 instrumentation/events/mainline/jbd2.h create mode 100644 instrumentation/events/mainline/kmem.h create mode 100644 instrumentation/events/mainline/lock.h create mode 100644 instrumentation/events/mainline/module.h create mode 100644 instrumentation/events/mainline/napi.h create mode 100644 instrumentation/events/mainline/net.h create mode 100644 instrumentation/events/mainline/power.h create mode 100644 instrumentation/events/mainline/regulator.h create mode 100644 instrumentation/events/mainline/scsi.h create mode 100644 instrumentation/events/mainline/skb.h create mode 100644 instrumentation/events/mainline/sock.h create mode 100644 instrumentation/events/mainline/udp.h create mode 100644 instrumentation/events/mainline/vmscan.h create mode 100644 probes/lttng-probe-asoc.c create mode 100644 probes/lttng-probe-ext3.c create mode 100644 probes/lttng-probe-gpio.c create mode 100644 probes/lttng-probe-jbd.c create mode 100644 probes/lttng-probe-jbd2.c create mode 100644 probes/lttng-probe-kmem.c create mode 100644 probes/lttng-probe-lock.c create mode 100644 probes/lttng-probe-module.c create mode 100644 probes/lttng-probe-napi.c create mode 100644 probes/lttng-probe-net.c create mode 100644 probes/lttng-probe-power.c create mode 100644 probes/lttng-probe-regulator.c create mode 100644 probes/lttng-probe-scsi.c create mode 100644 probes/lttng-probe-skb.c create mode 100644 probes/lttng-probe-sock.c create mode 100644 probes/lttng-probe-udp.c create mode 100644 probes/lttng-probe-vmscan.c diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h new file mode 100644 index 0000000..cb9e701 --- /dev/null +++ b/instrumentation/events/lttng-module/asoc.h @@ -0,0 +1,340 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM asoc + +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ASOC_H + +#include +#include +#include + +#ifndef _TRACE_ASOC_DEF +#define _TRACE_ASOC_DEF +struct snd_soc_jack; +struct snd_soc_codec; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) +struct snd_soc_platform; +#endif +struct snd_soc_card; +struct snd_soc_dapm_widget; +#endif + +/* + * Log register events + */ +DECLARE_EVENT_CLASS(snd_soc_reg, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val), + + TP_STRUCT__entry( + __string( name, codec->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, codec->name); + tp_assign(id, codec->id); + tp_assign(reg, reg); + tp_assign(val, val); + ), + + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +) + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +) + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) +DECLARE_EVENT_CLASS(snd_soc_preg, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val), + + TP_STRUCT__entry( + __string( name, platform->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, platform->name); + tp_assign(id, platform->id); + tp_assign(reg, reg); + tp_assign(val, val); + ), + + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +) + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +) + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +) +#endif + +DECLARE_EVENT_CLASS(snd_soc_card, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, card->name); + tp_assign(val, val); + ), + + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) +) + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +) + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +) + +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + ), + + TP_fast_assign( + tp_strcpy(name, card->name); + ), + + TP_printk("card=%s", __get_str(name)) +) + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +) + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +) + +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val), + + TP_STRUCT__entry( + __string( name, w->name ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, w->name); + tp_assign(val, val); + ), + + TP_printk("widget=%s val=%d", __get_str(name), + (int)__entry->val) +) + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +) + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +) + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +) + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) +TRACE_EVENT(snd_soc_dapm_walk_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, power_checks ) + __field( int, path_checks ) + __field( int, neighbour_checks ) + ), + + TP_fast_assign( + tp_strcpy(name, card->name); + tp_assign(power_checks, card->dapm_stats.power_checks); + tp_assign(path_checks, card->dapm_stats.path_checks); + tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks); + ), + + TP_printk("%s: checks %d power, %d path, %d neighbour", + __get_str(name), (int)__entry->power_checks, + (int)__entry->path_checks, (int)__entry->neighbour_checks) +) +#endif + +TRACE_EVENT(snd_soc_jack_irq, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + ), + + TP_printk("%s", __get_str(name)) +) + +TRACE_EVENT(snd_soc_jack_report, + + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), + + TP_ARGS(jack, mask, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, mask ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, jack->jack->name); + tp_assign(mask, mask); + tp_assign(val, val); + ), + + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, + (int)__entry->mask) +) + +TRACE_EVENT(snd_soc_jack_notify, + + TP_PROTO(struct snd_soc_jack *jack, int val), + + TP_ARGS(jack, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, jack->jack->name); + tp_assign(val, val); + ), + + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) +) + +TRACE_EVENT(snd_soc_cache_sync, + + TP_PROTO(struct snd_soc_codec *codec, const char *type, + const char *status), + + TP_ARGS(codec, type, status), + + TP_STRUCT__entry( + __string( name, codec->name ) + __string( status, status ) + __string( type, type ) + __field( int, id ) + ), + + TP_fast_assign( + tp_strcpy(name, codec->name); + tp_strcpy(status, status); + tp_strcpy(type, type); + tp_assign(id, codec->id); + ), + + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), + (int)__entry->id, __get_str(type), __get_str(status)) +) + +#endif /* _TRACE_ASOC_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h new file mode 100644 index 0000000..e02ecf4 --- /dev/null +++ b/instrumentation/events/lttng-module/ext3.h @@ -0,0 +1,870 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext3 + +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EXT3_H + +#include + +#ifndef _TRACE_EXT3_DEF +#define _TRACE_EXT3_DEF +static struct dentry *dentry; +#endif + + +TRACE_EVENT(ext3_free_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( uid_t, uid ) + __field( gid_t, gid ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(mode, inode->i_mode); + tp_assign(uid, inode->i_uid); + tp_assign(gid, inode->i_gid); + tp_assign(blocks, inode->i_blocks); + ), + + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->uid, __entry->gid, + (unsigned long) __entry->blocks) +) + +TRACE_EVENT(ext3_request_inode, + TP_PROTO(struct inode *dir, int mode), + + TP_ARGS(dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + tp_assign(dev, dir->i_sb->s_dev); + tp_assign(dir, dir->i_ino); + tp_assign(mode, mode); + ), + + TP_printk("dev %d,%d dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->dir, __entry->mode) +) + +TRACE_EVENT(ext3_allocate_inode, + TP_PROTO(struct inode *inode, struct inode *dir, int mode), + + TP_ARGS(inode, dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(dir, dir->i_ino); + tp_assign(mode, mode); + ), + + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->dir, __entry->mode) +) + +TRACE_EVENT(ext3_evict_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, nlink ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(nlink, inode->i_nlink); + ), + + TP_printk("dev %d,%d ino %lu nlink %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->nlink) +) + +TRACE_EVENT(ext3_drop_inode, + TP_PROTO(struct inode *inode, int drop), + + TP_ARGS(inode, drop), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, drop ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(drop, drop); + ), + + TP_printk("dev %d,%d ino %lu drop %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->drop) +) + +TRACE_EVENT(ext3_mark_inode_dirty, + TP_PROTO(struct inode *inode, unsigned long IP), + + TP_ARGS(inode, IP), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field(unsigned long, ip ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(ip, IP); + ), + + TP_printk("dev %d,%d ino %lu caller %pF", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (void *)__entry->ip) +) + +TRACE_EVENT(ext3_write_begin, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), + + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, flags ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(pos, pos); + tp_assign(len, len); + tp_assign(flags, flags); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->flags) +) + +DECLARE_EVENT_CLASS(ext3__write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(pos, pos); + tp_assign(len, len); + tp_assign(copied, copied); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->copied) +) + +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +) + +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +) + +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +) + +DECLARE_EVENT_CLASS(ext3__page_op, + TP_PROTO(struct page *page), + + TP_ARGS(page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + tp_assign(index, page->index); + tp_assign(ino, page->mapping->host->i_ino); + tp_assign(dev, page->mapping->host->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu page_index %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->index) +) + +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_readpage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +DEFINE_EVENT(ext3__page_op, ext3_releasepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +) + +TRACE_EVENT(ext3_invalidatepage, + TP_PROTO(struct page *page, unsigned long offset), + + TP_ARGS(page, offset), + + TP_STRUCT__entry( + __field( pgoff_t, index ) + __field( unsigned long, offset ) + __field( ino_t, ino ) + __field( dev_t, dev ) + + ), + + TP_fast_assign( + tp_assign(index, page->index); + tp_assign(offset, offset); + tp_assign(ino, page->mapping->host->i_ino); + tp_assign(dev, page->mapping->host->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->index, __entry->offset) +) + +TRACE_EVENT(ext3_discard_blocks, + TP_PROTO(struct super_block *sb, unsigned long blk, + unsigned long count), + + TP_ARGS(sb, blk, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, blk ) + __field( unsigned long, count ) + + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(blk, blk); + tp_assign(count, count); + ), + + TP_printk("dev %d,%d blk %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->blk, __entry->count) +) + +TRACE_EVENT(ext3_request_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count), + + TP_ARGS(inode, goal, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(count, count); + tp_assign(goal, goal); + ), + + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->goal) +) + +TRACE_EVENT(ext3_allocate_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count, unsigned long block), + + TP_ARGS(inode, goal, count, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, block ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(block, block); + tp_assign(count, count); + tp_assign(goal, goal); + ), + + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->block, + __entry->goal) +) + +TRACE_EVENT(ext3_free_blocks, + TP_PROTO(struct inode *inode, unsigned long block, + unsigned long count), + + TP_ARGS(inode, block, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( unsigned long, block ) + __field( unsigned long, count ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(mode, inode->i_mode); + tp_assign(block, block); + tp_assign(count, count); + ), + + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->block, __entry->count) +) + +TRACE_EVENT(ext3_sync_file_enter, + TP_PROTO(struct file *file, int datasync), + + TP_ARGS(file, datasync), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, parent ) + __field( int, datasync ) + ), + + TP_fast_assign( + dentry = file->f_path.dentry; + + tp_assign(dev, dentry->d_inode->i_sb->s_dev); + tp_assign(ino, dentry->d_inode->i_ino); + tp_assign(datasync, datasync); + tp_assign(parent, dentry->d_parent->d_inode->i_ino); + ), + + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->parent, __entry->datasync) +) + +TRACE_EVENT(ext3_sync_file_exit, + TP_PROTO(struct inode *inode, int ret), + + TP_ARGS(inode, ret), + + TP_STRUCT__entry( + __field( int, ret ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(ret, ret); + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +) + +TRACE_EVENT(ext3_sync_fs, + TP_PROTO(struct super_block *sb, int wait), + + TP_ARGS(sb, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(wait, wait); + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +) + +TRACE_EVENT(ext3_rsv_window_add, + TP_PROTO(struct super_block *sb, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(start, rsv_node->rsv_window._rsv_start); + tp_assign(end, rsv_node->rsv_window._rsv_end); + ), + + TP_printk("dev %d,%d start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->start, __entry->end) +) + +TRACE_EVENT(ext3_discard_reservation, + TP_PROTO(struct inode *inode, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(inode, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(start, rsv_node->rsv_window._rsv_start); + tp_assign(end, rsv_node->rsv_window._rsv_end); + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long)__entry->ino, __entry->start, + __entry->end) +) + +TRACE_EVENT(ext3_alloc_new_reservation, + TP_PROTO(struct super_block *sb, unsigned long goal), + + TP_ARGS(sb, goal), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(goal, goal); + ), + + TP_printk("dev %d,%d goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->goal) +) + +TRACE_EVENT(ext3_reserved, + TP_PROTO(struct super_block *sb, unsigned long block, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, block, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, block ) + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(block, block); + tp_assign(start, rsv_node->rsv_window._rsv_start); + tp_assign(end, rsv_node->rsv_window._rsv_end); + tp_assign(dev, sb->s_dev); + ), + + TP_printk("dev %d,%d block %lu, start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->block, __entry->start, __entry->end) +) + +TRACE_EVENT(ext3_forget, + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), + + TP_ARGS(inode, is_metadata, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( int, is_metadata ) + __field( unsigned long, block ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + tp_assign(mode, inode->i_mode); + tp_assign(is_metadata, is_metadata); + tp_assign(block, block); + ), + + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->is_metadata, __entry->block) +) + +TRACE_EVENT(ext3_read_block_bitmap, + TP_PROTO(struct super_block *sb, unsigned int group), + + TP_ARGS(sb, group), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( __u32, group ) + + ), + + TP_fast_assign( + tp_assign(dev, sb->s_dev); + tp_assign(group, group); + ), + + TP_printk("dev %d,%d group %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->group) +) + +TRACE_EVENT(ext3_direct_IO_enter, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), + + TP_ARGS(inode, offset, len, rw), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(pos, offset); + tp_assign(len, len); + tp_assign(rw, rw); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw) +) + +TRACE_EVENT(ext3_direct_IO_exit, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, + int rw, int ret), + + TP_ARGS(inode, offset, len, rw, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(pos, offset); + tp_assign(len, len); + tp_assign(rw, rw); + tp_assign(ret, ret); + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw, __entry->ret) +) + +TRACE_EVENT(ext3_unlink_enter, + TP_PROTO(struct inode *parent, struct dentry *dentry), + + TP_ARGS(parent, dentry), + + TP_STRUCT__entry( + __field( ino_t, parent ) + __field( ino_t, ino ) + __field( loff_t, size ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(parent, parent->i_ino); + tp_assign(ino, dentry->d_inode->i_ino); + tp_assign(size, dentry->d_inode->i_size); + tp_assign(dev, dentry->d_inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu size %lld parent %ld", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long)__entry->size, + (unsigned long) __entry->parent) +) + +TRACE_EVENT(ext3_unlink_exit, + TP_PROTO(struct dentry *dentry, int ret), + + TP_ARGS(dentry, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ino, dentry->d_inode->i_ino); + tp_assign(dev, dentry->d_inode->i_sb->s_dev); + tp_assign(ret, ret); + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +) + +DECLARE_EVENT_CLASS(ext3__truncate, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(blocks, inode->i_blocks); + ), + + TP_printk("dev %d,%d ino %lu blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) +) + +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +) + +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +) + +TRACE_EVENT(ext3_get_blocks_enter, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long len, int create), + + TP_ARGS(inode, lblk, len, create), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, len ) + __field( int, create ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(lblk, lblk); + tp_assign(len, len); + tp_assign(create, create); + ), + + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->len, __entry->create) +) + +TRACE_EVENT(ext3_get_blocks_exit, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long pblk, unsigned long len, int ret), + + TP_ARGS(inode, lblk, pblk, len, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, pblk ) + __field( unsigned long, len ) + __field( int, ret ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(lblk, lblk); + tp_assign(pblk, pblk); + tp_assign(len, len); + tp_assign(ret, ret); + ), + + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->pblk, + __entry->len, __entry->ret) +) + +TRACE_EVENT(ext3_load_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev); + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +) + +#endif /* _TRACE_EXT3_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/gpio.h b/instrumentation/events/lttng-module/gpio.h new file mode 100644 index 0000000..e6002c4 --- /dev/null +++ b/instrumentation/events/lttng-module/gpio.h @@ -0,0 +1,56 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM gpio + +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_GPIO_H + +#include + +TRACE_EVENT(gpio_direction, + + TP_PROTO(unsigned gpio, int in, int err), + + TP_ARGS(gpio, in, err), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, in) + __field(int, err) + ), + + TP_fast_assign( + tp_assign(gpio, gpio); + tp_assign(in, in); + tp_assign(err, err); + ), + + TP_printk("%u %3s (%d)", __entry->gpio, + __entry->in ? "in" : "out", __entry->err) +) + +TRACE_EVENT(gpio_value, + + TP_PROTO(unsigned gpio, int get, int value), + + TP_ARGS(gpio, get, value), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, get) + __field(int, value) + ), + + TP_fast_assign( + tp_assign(gpio, gpio); + tp_assign(get, get); + tp_assign(value, value); + ), + + TP_printk("%u %3s %d", __entry->gpio, + __entry->get ? "get" : "set", __entry->value) +) + +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h new file mode 100644 index 0000000..97ba1e5 --- /dev/null +++ b/instrumentation/events/lttng-module/jbd.h @@ -0,0 +1,243 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd + +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD_H + +#include +#include + +TRACE_EVENT(jbd_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(result, result); + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->result) +) + +DECLARE_EVENT_CLASS(jbd_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +#else + TP_printk("dev %d,%d transaction %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction) +#endif +) + +DEFINE_EVENT(jbd_commit, jbd_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd_commit, jbd_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd_commit, jbd_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +TRACE_EVENT(jbd_drop_transaction, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +#else + TP_printk("dev %d,%d transaction %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction) +#endif +) + +TRACE_EVENT(jbd_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + tp_assign(head, journal->j_tail_sequence); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +#else + TP_printk("dev %d,%d transaction %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->head) +#endif +) + +TRACE_EVENT(jbd_do_submit_data, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + __field( char, sync_commit ) +#endif + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); +#endif + tp_assign(transaction, commit_transaction->t_tid); + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +#else + TP_printk("dev %d,%d transaction %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction) +#endif +) + +TRACE_EVENT(jbd_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(tail_sequence, journal->j_tail_sequence); + tp_assign(first_tid, first_tid); + tp_assign(block_nr, block_nr); + tp_assign(freed, freed); + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +) + +TRACE_EVENT(jbd_update_superblock_end, + TP_PROTO(journal_t *journal, int wait), + + TP_ARGS(journal, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(wait, wait); + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +) + +#endif /* _TRACE_JBD_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h new file mode 100644 index 0000000..2e80832 --- /dev/null +++ b/instrumentation/events/lttng-module/jbd2.h @@ -0,0 +1,238 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd2 + +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD2_H + +#include +#include + +#ifndef _TRACE_JBD2_DEF +#define _TRACE_JBD2_DEF +struct transaction_chp_stats_s; +struct transaction_run_stats_s; +#endif + +TRACE_EVENT(jbd2_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(result, result); + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) +) + +DECLARE_EVENT_CLASS(jbd2_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(transaction, commit_transaction->t_tid); + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +) + +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) + +TRACE_EVENT(jbd2_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(transaction, commit_transaction->t_tid); + tp_assign(head, journal->j_tail_sequence); + ), + + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +) + +TRACE_EVENT(jbd2_submit_inode_data, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + ), + + TP_fast_assign( + tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino); + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +) + +TRACE_EVENT(jbd2_run_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_run_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, wait ) + __field( unsigned long, running ) + __field( unsigned long, locked ) + __field( unsigned long, flushing ) + __field( unsigned long, logging ) + __field( __u32, handle_count ) + __field( __u32, blocks ) + __field( __u32, blocks_logged ) + ), + + TP_fast_assign( + tp_assign(dev, dev); + tp_assign(tid, tid); + tp_assign(wait, stats->rs_wait); + tp_assign(running, stats->rs_running); + tp_assign(locked, stats->rs_locked); + tp_assign(flushing, stats->rs_flushing); + tp_assign(logging, stats->rs_logging); + tp_assign(handle_count, stats->rs_handle_count); + tp_assign(blocks, stats->rs_blocks); + tp_assign(blocks_logged, stats->rs_blocks_logged); + ), + + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " + "logging %u handle_count %u blocks %u blocks_logged %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->wait), + jiffies_to_msecs(__entry->running), + jiffies_to_msecs(__entry->locked), + jiffies_to_msecs(__entry->flushing), + jiffies_to_msecs(__entry->logging), + __entry->handle_count, __entry->blocks, + __entry->blocks_logged) +) + +TRACE_EVENT(jbd2_checkpoint_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_chp_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, chp_time ) + __field( __u32, forced_to_close ) + __field( __u32, written ) + __field( __u32, dropped ) + ), + + TP_fast_assign( + tp_assign(dev, dev); + tp_assign(tid, tid); + tp_assign(chp_time, stats->cs_chp_time); + tp_assign(forced_to_close, stats->cs_forced_to_close); + tp_assign(written, stats->cs_written); + tp_assign(dropped, stats->cs_dropped); + ), + + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " + "written %u dropped %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->chp_time), + __entry->forced_to_close, __entry->written, __entry->dropped) +) + +TRACE_EVENT(jbd2_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(tail_sequence, journal->j_tail_sequence); + tp_assign(first_tid, first_tid); + tp_assign(block_nr, block_nr); + tp_assign(freed, freed); + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +) + +#endif /* _TRACE_JBD2_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h new file mode 100644 index 0000000..04f668b --- /dev/null +++ b/instrumentation/events/lttng-module/kmem.h @@ -0,0 +1,304 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kmem + +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KMEM_H + +DECLARE_EVENT_CLASS(kmem_alloc, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + tp_assign(call_site, call_site); + tp_assign(ptr, ptr); + tp_assign(bytes_req, bytes_req); + tp_assign(bytes_alloc, bytes_alloc); + tp_assign(gfp_flags, gfp_flags); + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags)) +) + +DEFINE_EVENT(kmem_alloc, kmalloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +) + +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +) + +DECLARE_EVENT_CLASS(kmem_alloc_node, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags, + int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + __field( int, node ) + ), + + TP_fast_assign( + tp_assign(call_site, call_site); + tp_assign(ptr, ptr); + tp_assign(bytes_req, bytes_req); + tp_assign(bytes_alloc, bytes_alloc); + tp_assign(gfp_flags, gfp_flags); + tp_assign(node, node); + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags), + __entry->node) +) + +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +) + +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +) + +DECLARE_EVENT_CLASS(kmem_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + ), + + TP_fast_assign( + tp_assign(call_site, call_site); + tp_assign(ptr, ptr); + ), + + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) +) + +DEFINE_EVENT(kmem_free, kfree, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +) + +DEFINE_EVENT(kmem_free, kmem_cache_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +) + +TRACE_EVENT(mm_page_free_direct, + + TP_PROTO(struct page *page, unsigned int order), + + TP_ARGS(page, order), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(order, order); + ), + + TP_printk("page=%p pfn=%lu order=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order) +) + +TRACE_EVENT(mm_pagevec_free, + + TP_PROTO(struct page *page, int cold), + + TP_ARGS(page, cold), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, cold ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(cold, cold); + ), + + TP_printk("page=%p pfn=%lu order=0 cold=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->cold) +) + +TRACE_EVENT(mm_page_alloc, + + TP_PROTO(struct page *page, unsigned int order, + gfp_t gfp_flags, int migratetype), + + TP_ARGS(page, order, gfp_flags, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( gfp_t, gfp_flags ) + __field( int, migratetype ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(order, order); + tp_assign(gfp_flags, gfp_flags); + tp_assign(migratetype, migratetype); + ), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + show_gfp_flags(__entry->gfp_flags)) +) + +DECLARE_EVENT_CLASS(mm_page, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( int, migratetype ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(order, order); + tp_assign(migratetype, migratetype); + ), + + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + __entry->order == 0) +) + +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype) +) + +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", + __entry->page, page_to_pfn(__entry->page), + __entry->order, __entry->migratetype) +) + +TRACE_EVENT(mm_page_alloc_extfrag, + + TP_PROTO(struct page *page, + int alloc_order, int fallback_order, + int alloc_migratetype, int fallback_migratetype), + + TP_ARGS(page, + alloc_order, fallback_order, + alloc_migratetype, fallback_migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, alloc_order ) + __field( int, fallback_order ) + __field( int, alloc_migratetype ) + __field( int, fallback_migratetype ) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(alloc_order, alloc_order); + tp_assign(fallback_order, fallback_order); + tp_assign(alloc_migratetype, alloc_migratetype); + tp_assign(fallback_migratetype, fallback_migratetype); + ), + + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->alloc_order, + __entry->fallback_order, + pageblock_order, + __entry->alloc_migratetype, + __entry->fallback_migratetype, + __entry->fallback_order < pageblock_order, + __entry->alloc_migratetype == __entry->fallback_migratetype) +) + +#endif /* _TRACE_KMEM_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/lock.h b/instrumentation/events/lttng-module/lock.h new file mode 100644 index 0000000..75101f6 --- /dev/null +++ b/instrumentation/events/lttng-module/lock.h @@ -0,0 +1,86 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lock + +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_LOCK_H + +#include +#include + +#ifdef CONFIG_LOCKDEP + +TRACE_EVENT(lock_acquire, + + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, + struct lockdep_map *next_lock, unsigned long ip), + + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), + + TP_STRUCT__entry( + __field(unsigned int, flags) + __string(name, lock->name) + __field(void *, lockdep_addr) + ), + + TP_fast_assign( + tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)); + tp_strcpy(name, lock->name); + tp_assign(lockdep_addr, lock); + ), + + TP_printk("%p %s%s%s", __entry->lockdep_addr, + (__entry->flags & 1) ? "try " : "", + (__entry->flags & 2) ? "read " : "", + __get_str(name)) +) + +DECLARE_EVENT_CLASS(lock, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip), + + TP_STRUCT__entry( + __string( name, lock->name ) + __field( void *, lockdep_addr ) + ), + + TP_fast_assign( + tp_strcpy(name, lock->name); + tp_assign(lockdep_addr, lock); + ), + + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) +) + +DEFINE_EVENT(lock, lock_release, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +) + +#ifdef CONFIG_LOCK_STAT + +DEFINE_EVENT(lock, lock_contended, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +) + +DEFINE_EVENT(lock, lock_acquired, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +) + +#endif +#endif + +#endif /* _TRACE_LOCK_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/module.h b/instrumentation/events/lttng-module/module.h new file mode 100644 index 0000000..2e83431 --- /dev/null +++ b/instrumentation/events/lttng-module/module.h @@ -0,0 +1,134 @@ +/* + * Because linux/module.h has tracepoints in the header, and ftrace.h + * eventually includes this file, define_trace.h includes linux/module.h + * But we do not want the module.h to override the TRACE_SYSTEM macro + * variable that define_trace.h is processing, so we only set it + * when module events are being processed, which would happen when + * CREATE_TRACE_POINTS is defined. + */ +#ifdef CREATE_TRACE_POINTS +#undef TRACE_SYSTEM +#define TRACE_SYSTEM module +#endif + +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MODULE_H + +#include + +#ifdef CONFIG_MODULES + +#ifndef _TRACE_MODULE_DEF +#define _TRACE_MODULE_DEF +struct module; + +#define show_module_flags(flags) __print_flags(flags, "", \ + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ + { (1UL << TAINT_FORCED_MODULE), "F" }, \ + { (1UL << TAINT_CRAP), "C" }) +#endif + +TRACE_EVENT(module_load, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __field( unsigned int, taints ) + __string( name, mod->name ) + ), + + TP_fast_assign( + tp_assign(taints, mod->taints); + tp_strcpy(name, mod->name); + ), + + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) +) + +TRACE_EVENT(module_free, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __string( name, mod->name ) + ), + + TP_fast_assign( + tp_strcpy(name, mod->name); + ), + + TP_printk("%s", __get_str(name)) +) + +#ifdef CONFIG_MODULE_UNLOAD +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ + +DECLARE_EVENT_CLASS(module_refcnt, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( int, refcnt ) + __string( name, mod->name ) + ), + + TP_fast_assign( + tp_assign(ip, ip); + tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)); + tp_strcpy(name, mod->name); + ), + + TP_printk("%s call_site=%pf refcnt=%d", + __get_str(name), (void *)__entry->ip, __entry->refcnt) +) + +DEFINE_EVENT(module_refcnt, module_get, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +) + +DEFINE_EVENT(module_refcnt, module_put, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +) +#endif /* CONFIG_MODULE_UNLOAD */ + +TRACE_EVENT(module_request, + + TP_PROTO(char *name, bool wait, unsigned long ip), + + TP_ARGS(name, wait, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( bool, wait ) + __string( name, name ) + ), + + TP_fast_assign( + tp_assign(ip, ip); + tp_assign(wait, wait); + tp_strcpy(name, name); + ), + + TP_printk("%s wait=%d call_site=%pf", + __get_str(name), (int)__entry->wait, (void *)__entry->ip) +) + +#endif /* CONFIG_MODULES */ + +#endif /* _TRACE_MODULE_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/napi.h b/instrumentation/events/lttng-module/napi.h new file mode 100644 index 0000000..58b8336 --- /dev/null +++ b/instrumentation/events/lttng-module/napi.h @@ -0,0 +1,38 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM napi + +#if !defined(_TRACE_NAPI_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NAPI_H_ + +#include +#include +#include + +#define NO_DEV "(no_device)" + +TRACE_EVENT(napi_poll, + + TP_PROTO(struct napi_struct *napi), + + TP_ARGS(napi), + + TP_STRUCT__entry( + __field( struct napi_struct *, napi) + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) + ), + + TP_fast_assign( + tp_assign(napi, napi); + tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV); + ), + + TP_printk("napi poll on napi struct %p for device %s", + __entry->napi, __get_str(dev_name)) +) + +#undef NO_DEV + +#endif /* _TRACE_NAPI_H_ */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h new file mode 100644 index 0000000..c25b0d9 --- /dev/null +++ b/instrumentation/events/lttng-module/net.h @@ -0,0 +1,84 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM net + +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NET_H + +#include +#include +#include +#include + +TRACE_EVENT(net_dev_xmit, + + TP_PROTO(struct sk_buff *skb, + int rc, + struct net_device *dev, + unsigned int skb_len), + + TP_ARGS(skb, rc, dev, skb_len), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __field( int, rc ) + __string( name, dev->name ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, skb_len); + tp_assign(rc, rc); + tp_strcpy(name, dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) +) + +DECLARE_EVENT_CLASS(net_dev_template, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __string( name, skb->dev->name ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, skb->len); + tp_strcpy(name, skb->dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u", + __get_str(name), __entry->skbaddr, __entry->len) +) + +DEFINE_EVENT(net_dev_template, net_dev_queue, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +) + +DEFINE_EVENT(net_dev_template, netif_receive_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +) + +DEFINE_EVENT(net_dev_template, netif_rx, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +) +#endif /* _TRACE_NET_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h new file mode 100644 index 0000000..05aced7 --- /dev/null +++ b/instrumentation/events/lttng-module/power.h @@ -0,0 +1,240 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM power + +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_POWER_H + +#include +#include + +DECLARE_EVENT_CLASS(cpu, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id), + + TP_STRUCT__entry( + __field( u32, state ) + __field( u32, cpu_id ) + ), + + TP_fast_assign( + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, + (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(cpu, cpu_idle, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id) +) + +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING + +#define PWR_EVENT_EXIT -1 +#endif + +DEFINE_EVENT(cpu, cpu_frequency, + + TP_PROTO(unsigned int frequency, unsigned int cpu_id), + + TP_ARGS(frequency, cpu_id) +) + +TRACE_EVENT(machine_suspend, + + TP_PROTO(unsigned int state), + + TP_ARGS(state), + + TP_STRUCT__entry( + __field( u32, state ) + ), + + TP_fast_assign( + tp_assign(state, state); + ), + + TP_printk("state=%lu", (unsigned long)__entry->state) +) + +/* This code will be removed after deprecation time exceeded (2.6.41) */ +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED + +/* + * The power events are used for cpuidle & suspend (power_start, power_end) + * and for cpufreq (power_frequency) + */ +DECLARE_EVENT_CLASS(power, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id), + + TP_STRUCT__entry( + __field( u64, type ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_assign(type, type); + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(power, power_start, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +) + +DEFINE_EVENT(power, power_frequency, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +) + +TRACE_EVENT(power_end, + + TP_PROTO(unsigned int cpu_id), + + TP_ARGS(cpu_id), + + TP_STRUCT__entry( + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) + +) + +/* Deprecated dummy functions must be protected against multi-declartion */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED + +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; + +/* These dummy declaration have to be ripped out when the deprecated + events get removed */ +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; +static inline void trace_power_end(u64 cpuid) {}; +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +/* + * The clock events are used for clock enable/disable and for + * clock rate change + */ +DECLARE_EVENT_CLASS(clock, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); + ), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(clock, clock_enable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) + +DEFINE_EVENT(clock, clock_disable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) + +DEFINE_EVENT(clock, clock_set_rate, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) + +/* + * The power domain events are used for power domains transitions + */ +DECLARE_EVENT_CLASS(power_domain, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(state, state); + tp_assign(cpu_id, cpu_id); +), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +) + +DEFINE_EVENT(power_domain, power_domain_target, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +) +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/regulator.h b/instrumentation/events/lttng-module/regulator.h new file mode 100644 index 0000000..e94da7c --- /dev/null +++ b/instrumentation/events/lttng-module/regulator.h @@ -0,0 +1,141 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM regulator + +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_REGULATOR_H + +#include +#include + +/* + * Events which just log themselves and the regulator name for enable/disable + * type tracking. + */ +DECLARE_EVENT_CLASS(regulator_basic, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + ), + + TP_printk("name=%s", __get_str(name)) + +) + +DEFINE_EVENT(regulator_basic, regulator_enable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_enable_delay, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_enable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_disable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +DEFINE_EVENT(regulator_basic, regulator_disable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +) + +/* + * Events that take a range of numerical values, mostly for voltages + * and so on. + */ +DECLARE_EVENT_CLASS(regulator_range, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max), + + TP_STRUCT__entry( + __string( name, name ) + __field( int, min ) + __field( int, max ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(min, min); + tp_assign(max, max); + ), + + TP_printk("name=%s (%d-%d)", __get_str(name), + (int)__entry->min, (int)__entry->max) +) + +DEFINE_EVENT(regulator_range, regulator_set_voltage, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max) + +) + + +/* + * Events that take a single value, mostly for readback and refcounts. + */ +DECLARE_EVENT_CLASS(regulator_value, + + TP_PROTO(const char *name, unsigned int val), + + TP_ARGS(name, val), + + TP_STRUCT__entry( + __string( name, name ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + tp_strcpy(name, name); + tp_assign(val, val); + ), + + TP_printk("name=%s, val=%u", __get_str(name), + (int)__entry->val) +) + +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, + + TP_PROTO(const char *name, unsigned int value), + + TP_ARGS(name, value) + +) + +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h new file mode 100644 index 0000000..27362f8 --- /dev/null +++ b/instrumentation/events/lttng-module/scsi.h @@ -0,0 +1,369 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM scsi + +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SCSI_H + +#include +#include +#include +#include + +#ifndef _TRACE_SCSI_DEF +#define _TRACE_SCSI_DEF + +#define scsi_opcode_name(opcode) { opcode, #opcode } +#define show_opcode_name(val) \ + __print_symbolic(val, \ + scsi_opcode_name(TEST_UNIT_READY), \ + scsi_opcode_name(REZERO_UNIT), \ + scsi_opcode_name(REQUEST_SENSE), \ + scsi_opcode_name(FORMAT_UNIT), \ + scsi_opcode_name(READ_BLOCK_LIMITS), \ + scsi_opcode_name(REASSIGN_BLOCKS), \ + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ + scsi_opcode_name(READ_6), \ + scsi_opcode_name(WRITE_6), \ + scsi_opcode_name(SEEK_6), \ + scsi_opcode_name(READ_REVERSE), \ + scsi_opcode_name(WRITE_FILEMARKS), \ + scsi_opcode_name(SPACE), \ + scsi_opcode_name(INQUIRY), \ + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ + scsi_opcode_name(MODE_SELECT), \ + scsi_opcode_name(RESERVE), \ + scsi_opcode_name(RELEASE), \ + scsi_opcode_name(COPY), \ + scsi_opcode_name(ERASE), \ + scsi_opcode_name(MODE_SENSE), \ + scsi_opcode_name(START_STOP), \ + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ + scsi_opcode_name(SEND_DIAGNOSTIC), \ + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ + scsi_opcode_name(SET_WINDOW), \ + scsi_opcode_name(READ_CAPACITY), \ + scsi_opcode_name(READ_10), \ + scsi_opcode_name(WRITE_10), \ + scsi_opcode_name(SEEK_10), \ + scsi_opcode_name(POSITION_TO_ELEMENT), \ + scsi_opcode_name(WRITE_VERIFY), \ + scsi_opcode_name(VERIFY), \ + scsi_opcode_name(SEARCH_HIGH), \ + scsi_opcode_name(SEARCH_EQUAL), \ + scsi_opcode_name(SEARCH_LOW), \ + scsi_opcode_name(SET_LIMITS), \ + scsi_opcode_name(PRE_FETCH), \ + scsi_opcode_name(READ_POSITION), \ + scsi_opcode_name(SYNCHRONIZE_CACHE), \ + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ + scsi_opcode_name(READ_DEFECT_DATA), \ + scsi_opcode_name(MEDIUM_SCAN), \ + scsi_opcode_name(COMPARE), \ + scsi_opcode_name(COPY_VERIFY), \ + scsi_opcode_name(WRITE_BUFFER), \ + scsi_opcode_name(READ_BUFFER), \ + scsi_opcode_name(UPDATE_BLOCK), \ + scsi_opcode_name(READ_LONG), \ + scsi_opcode_name(WRITE_LONG), \ + scsi_opcode_name(CHANGE_DEFINITION), \ + scsi_opcode_name(WRITE_SAME), \ + scsi_opcode_name(UNMAP), \ + scsi_opcode_name(READ_TOC), \ + scsi_opcode_name(LOG_SELECT), \ + scsi_opcode_name(LOG_SENSE), \ + scsi_opcode_name(XDWRITEREAD_10), \ + scsi_opcode_name(MODE_SELECT_10), \ + scsi_opcode_name(RESERVE_10), \ + scsi_opcode_name(RELEASE_10), \ + scsi_opcode_name(MODE_SENSE_10), \ + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ + scsi_opcode_name(REPORT_LUNS), \ + scsi_opcode_name(MAINTENANCE_IN), \ + scsi_opcode_name(MAINTENANCE_OUT), \ + scsi_opcode_name(MOVE_MEDIUM), \ + scsi_opcode_name(EXCHANGE_MEDIUM), \ + scsi_opcode_name(READ_12), \ + scsi_opcode_name(WRITE_12), \ + scsi_opcode_name(WRITE_VERIFY_12), \ + scsi_opcode_name(SEARCH_HIGH_12), \ + scsi_opcode_name(SEARCH_EQUAL_12), \ + scsi_opcode_name(SEARCH_LOW_12), \ + scsi_opcode_name(READ_ELEMENT_STATUS), \ + scsi_opcode_name(SEND_VOLUME_TAG), \ + scsi_opcode_name(WRITE_LONG_2), \ + scsi_opcode_name(READ_16), \ + scsi_opcode_name(WRITE_16), \ + scsi_opcode_name(VERIFY_16), \ + scsi_opcode_name(WRITE_SAME_16), \ + scsi_opcode_name(SERVICE_ACTION_IN), \ + scsi_opcode_name(SAI_READ_CAPACITY_16), \ + scsi_opcode_name(SAI_GET_LBA_STATUS), \ + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ + scsi_opcode_name(MO_SET_TARGET_PGS), \ + scsi_opcode_name(READ_32), \ + scsi_opcode_name(WRITE_32), \ + scsi_opcode_name(WRITE_SAME_32), \ + scsi_opcode_name(ATA_16), \ + scsi_opcode_name(ATA_12)) + +#define scsi_hostbyte_name(result) { result, #result } +#define show_hostbyte_name(val) \ + __print_symbolic(val, \ + scsi_hostbyte_name(DID_OK), \ + scsi_hostbyte_name(DID_NO_CONNECT), \ + scsi_hostbyte_name(DID_BUS_BUSY), \ + scsi_hostbyte_name(DID_TIME_OUT), \ + scsi_hostbyte_name(DID_BAD_TARGET), \ + scsi_hostbyte_name(DID_ABORT), \ + scsi_hostbyte_name(DID_PARITY), \ + scsi_hostbyte_name(DID_ERROR), \ + scsi_hostbyte_name(DID_RESET), \ + scsi_hostbyte_name(DID_BAD_INTR), \ + scsi_hostbyte_name(DID_PASSTHROUGH), \ + scsi_hostbyte_name(DID_SOFT_ERROR), \ + scsi_hostbyte_name(DID_IMM_RETRY), \ + scsi_hostbyte_name(DID_REQUEUE), \ + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) + +#define scsi_driverbyte_name(result) { result, #result } +#define show_driverbyte_name(val) \ + __print_symbolic(val, \ + scsi_driverbyte_name(DRIVER_OK), \ + scsi_driverbyte_name(DRIVER_BUSY), \ + scsi_driverbyte_name(DRIVER_SOFT), \ + scsi_driverbyte_name(DRIVER_MEDIA), \ + scsi_driverbyte_name(DRIVER_ERROR), \ + scsi_driverbyte_name(DRIVER_INVALID), \ + scsi_driverbyte_name(DRIVER_TIMEOUT), \ + scsi_driverbyte_name(DRIVER_HARD), \ + scsi_driverbyte_name(DRIVER_SENSE)) + +#define scsi_msgbyte_name(result) { result, #result } +#define show_msgbyte_name(val) \ + __print_symbolic(val, \ + scsi_msgbyte_name(COMMAND_COMPLETE), \ + scsi_msgbyte_name(EXTENDED_MESSAGE), \ + scsi_msgbyte_name(SAVE_POINTERS), \ + scsi_msgbyte_name(RESTORE_POINTERS), \ + scsi_msgbyte_name(DISCONNECT), \ + scsi_msgbyte_name(INITIATOR_ERROR), \ + scsi_msgbyte_name(ABORT_TASK_SET), \ + scsi_msgbyte_name(MESSAGE_REJECT), \ + scsi_msgbyte_name(NOP), \ + scsi_msgbyte_name(MSG_PARITY_ERROR), \ + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ + scsi_msgbyte_name(TARGET_RESET), \ + scsi_msgbyte_name(ABORT_TASK), \ + scsi_msgbyte_name(CLEAR_TASK_SET), \ + scsi_msgbyte_name(INITIATE_RECOVERY), \ + scsi_msgbyte_name(RELEASE_RECOVERY), \ + scsi_msgbyte_name(CLEAR_ACA), \ + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ + scsi_msgbyte_name(ACA), \ + scsi_msgbyte_name(QAS_REQUEST), \ + scsi_msgbyte_name(BUS_DEVICE_RESET), \ + scsi_msgbyte_name(ABORT)) + +#define scsi_statusbyte_name(result) { result, #result } +#define show_statusbyte_name(val) \ + __print_symbolic(val, \ + scsi_statusbyte_name(SAM_STAT_GOOD), \ + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_BUSY), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) + +#define scsi_prot_op_name(result) { result, #result } +#define show_prot_op_name(val) \ + __print_symbolic(val, \ + scsi_prot_op_name(SCSI_PROT_NORMAL), \ + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) + +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) +#endif + +TRACE_EVENT(scsi_dispatch_cmd_start, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + tp_assign(host_no, cmd->device->host->host_no); + tp_assign(channel, cmd->device->channel); + tp_assign(id, cmd->device->id); + tp_assign(lun, cmd->device->lun); + tp_assign(opcode, cmd->cmnd[0]); + tp_assign(cmd_len, cmd->cmd_len); + tp_assign(data_sglen, scsi_sg_count(cmd)); + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); + tp_assign(prot_op, scsi_get_prot_op(cmd)); + tp_memcpy_dyn(cmnd, cmd->cmnd); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) +) + +TRACE_EVENT(scsi_dispatch_cmd_error, + + TP_PROTO(struct scsi_cmnd *cmd, int rtn), + + TP_ARGS(cmd, rtn), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, rtn ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + tp_assign(host_no, cmd->device->host->host_no); + tp_assign(channel, cmd->device->channel); + tp_assign(id, cmd->device->id); + tp_assign(lun, cmd->device->lun); + tp_assign(rtn, rtn); + tp_assign(opcode, cmd->cmnd[0]); + tp_assign(cmd_len, cmd->cmd_len); + tp_assign(data_sglen, scsi_sg_count(cmd)); + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); + tp_assign(prot_op, scsi_get_prot_op(cmd)); + tp_memcpy_dyn(cmnd, cmd->cmnd); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + __entry->rtn) +) + +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, result ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + tp_assign(host_no, cmd->device->host->host_no); + tp_assign(channel, cmd->device->channel); + tp_assign(id, cmd->device->id); + tp_assign(lun, cmd->device->lun); + tp_assign(result, cmd->result); + tp_assign(opcode, cmd->cmnd[0]); + tp_assign(cmd_len, cmd->cmd_len); + tp_assign(data_sglen, scsi_sg_count(cmd)); + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); + tp_assign(prot_op, scsi_get_prot_op(cmd)); + tp_memcpy_dyn(cmnd, cmd->cmnd); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ + "%s host=%s message=%s status=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + show_driverbyte_name(((__entry->result) >> 24) & 0xff), + show_hostbyte_name(((__entry->result) >> 16) & 0xff), + show_msgbyte_name(((__entry->result) >> 8) & 0xff), + show_statusbyte_name(__entry->result & 0xff)) +) + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)) + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)) + +TRACE_EVENT(scsi_eh_wakeup, + + TP_PROTO(struct Scsi_Host *shost), + + TP_ARGS(shost), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + ), + + TP_fast_assign( + tp_assign(host_no, shost->host_no); + ), + + TP_printk("host_no=%u", __entry->host_no) +) + +#endif /* _TRACE_SCSI_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/skb.h b/instrumentation/events/lttng-module/skb.h new file mode 100644 index 0000000..9a79449 --- /dev/null +++ b/instrumentation/events/lttng-module/skb.h @@ -0,0 +1,75 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM skb + +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SKB_H + +#include +#include +#include + +/* + * Tracepoint for free an sk_buff: + */ +TRACE_EVENT(kfree_skb, + + TP_PROTO(struct sk_buff *skb, void *location), + + TP_ARGS(skb, location), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( void *, location ) + __field( unsigned short, protocol ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(location, location); + tp_assign(protocol, ntohs(skb->protocol)); + ), + + TP_printk("skbaddr=%p protocol=%u location=%p", + __entry->skbaddr, __entry->protocol, __entry->location) +) + +TRACE_EVENT(consume_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + ), + + TP_printk("skbaddr=%p", __entry->skbaddr) +) + +TRACE_EVENT(skb_copy_datagram_iovec, + + TP_PROTO(const struct sk_buff *skb, int len), + + TP_ARGS(skb, len), + + TP_STRUCT__entry( + __field( const void *, skbaddr ) + __field( int, len ) + ), + + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, len); + ), + + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) +) + +#endif /* _TRACE_SKB_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h new file mode 100644 index 0000000..246ea58 --- /dev/null +++ b/instrumentation/events/lttng-module/sock.h @@ -0,0 +1,68 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sock + +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SOCK_H + +#include +#include + +TRACE_EVENT(sock_rcvqueue_full, + + TP_PROTO(struct sock *sk, struct sk_buff *skb), + + TP_ARGS(sk, skb), + + TP_STRUCT__entry( + __field(int, rmem_alloc) + __field(unsigned int, truesize) + __field(int, sk_rcvbuf) + ), + + TP_fast_assign( + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); + tp_assign(truesize, skb->truesize); + tp_assign(sk_rcvbuf, sk->sk_rcvbuf); + ), + + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) +) + +TRACE_EVENT(sock_exceed_buf_limit, + + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), + + TP_ARGS(sk, prot, allocated), + + TP_STRUCT__entry( + __string(name, prot->name) + __field(long *, sysctl_mem) + __field(long, allocated) + __field(int, sysctl_rmem) + __field(int, rmem_alloc) + ), + + TP_fast_assign( + tp_strcpy(name, prot->name); + tp_assign(sysctl_mem, prot->sysctl_mem); + tp_assign(allocated, allocated); + tp_assign(sysctl_rmem, prot->sysctl_rmem[0]); + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); + ), + + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " + "sysctl_rmem=%d rmem_alloc=%d", + __entry->name, + __entry->sysctl_mem[0], + __entry->sysctl_mem[1], + __entry->sysctl_mem[2], + __entry->allocated, + __entry->sysctl_rmem, + __entry->rmem_alloc) +) + +#endif /* _TRACE_SOCK_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/udp.h b/instrumentation/events/lttng-module/udp.h new file mode 100644 index 0000000..304ea95 --- /dev/null +++ b/instrumentation/events/lttng-module/udp.h @@ -0,0 +1,32 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM udp + +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_UDP_H + +#include +#include + +TRACE_EVENT(udp_fail_queue_rcv_skb, + + TP_PROTO(int rc, struct sock *sk), + + TP_ARGS(rc, sk), + + TP_STRUCT__entry( + __field(int, rc) + __field(__u16, lport) + ), + + TP_fast_assign( + tp_assign(rc, rc); + tp_assign(lport, inet_sk(sk)->inet_num); + ), + + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) +) + +#endif /* _TRACE_UDP_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h new file mode 100644 index 0000000..aa022e2 --- /dev/null +++ b/instrumentation/events/lttng-module/vmscan.h @@ -0,0 +1,499 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vmscan + +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_VMSCAN_H + +TRACE_EVENT(mm_vmscan_kswapd_sleep, + + TP_PROTO(int nid), + + TP_ARGS(nid), + + TP_STRUCT__entry( + __field( int, nid ) + ), + + TP_fast_assign( + tp_assign(nid, nid); + ), + + TP_printk("nid=%d", __entry->nid) +) + +TRACE_EVENT(mm_vmscan_kswapd_wake, + + TP_PROTO(int nid, int order), + + TP_ARGS(nid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, order ) + ), + + TP_fast_assign( + tp_assign(nid, nid); + tp_assign(order, order); + ), + + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) +) + +TRACE_EVENT(mm_vmscan_wakeup_kswapd, + + TP_PROTO(int nid, int zid, int order), + + TP_ARGS(nid, zid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, zid ) + __field( int, order ) + ), + + TP_fast_assign( + tp_assign(nid, nid); + tp_assign(zid, zid); + tp_assign(order, order); + ), + + TP_printk("nid=%d zid=%d order=%d", + __entry->nid, + __entry->zid, + __entry->order) +) + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags), + + TP_STRUCT__entry( + __field( int, order ) + __field( int, may_writepage ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + tp_assign(order, order); + tp_assign(may_writepage, may_writepage); + tp_assign(gfp_flags, gfp_flags); + ), + + TP_printk("order=%d may_writepage=%d gfp_flags=%s", + __entry->order, + __entry->may_writepage, + show_gfp_flags(__entry->gfp_flags)) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +) + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed), + + TP_STRUCT__entry( + __field( unsigned long, nr_reclaimed ) + ), + + TP_fast_assign( + tp_assign(nr_reclaimed, nr_reclaimed); + ), + + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +) + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +) + +TRACE_EVENT(mm_shrink_slab_start, + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, + long nr_objects_to_shrink, unsigned long pgs_scanned, + unsigned long lru_pgs, unsigned long cache_items, + unsigned long long delta, unsigned long total_scan), + + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, + cache_items, delta, total_scan), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, nr_objects_to_shrink) + __field(gfp_t, gfp_flags) + __field(unsigned long, pgs_scanned) + __field(unsigned long, lru_pgs) + __field(unsigned long, cache_items) + __field(unsigned long long, delta) + __field(unsigned long, total_scan) + ), + + TP_fast_assign( + tp_assign(shr,shr); + tp_assign(shrink, shr->shrink); + tp_assign(nr_objects_to_shrink, nr_objects_to_shrink); + tp_assign(gfp_flags, sc->gfp_mask); + tp_assign(pgs_scanned, pgs_scanned); + tp_assign(lru_pgs, lru_pgs); + tp_assign(cache_items, cache_items); + tp_assign(delta, delta); + tp_assign(total_scan, total_scan); + ), + + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", + __entry->shrink, + __entry->shr, + __entry->nr_objects_to_shrink, + show_gfp_flags(__entry->gfp_flags), + __entry->pgs_scanned, + __entry->lru_pgs, + __entry->cache_items, + __entry->delta, + __entry->total_scan) +) + +TRACE_EVENT(mm_shrink_slab_end, + TP_PROTO(struct shrinker *shr, int shrinker_retval, + long unused_scan_cnt, long new_scan_cnt), + + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, unused_scan) + __field(long, new_scan) + __field(int, retval) + __field(long, total_scan) + ), + + TP_fast_assign( + tp_assign(shr, shr); + tp_assign(shrink, shr->shrink); + tp_assign(unused_scan, unused_scan_cnt); + tp_assign(new_scan, new_scan_cnt); + tp_assign(retval, shrinker_retval); + tp_assign(total_scan, new_scan_cnt - unused_scan_cnt); + ), + + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", + __entry->shrink, + __entry->shr, + __entry->unused_scan, + __entry->new_scan, + __entry->total_scan, + __entry->retval) +) + +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + isolate_mode_t isolate_mode), +#else + isolate_mode_t isolate_mode, + int file), +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), +#else + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file), +#endif + + TP_STRUCT__entry( + __field(int, order) + __field(unsigned long, nr_requested) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_taken) + __field(unsigned long, nr_lumpy_taken) + __field(unsigned long, nr_lumpy_dirty) + __field(unsigned long, nr_lumpy_failed) + __field(isolate_mode_t, isolate_mode) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + __field(int, file) +#endif + ), + + TP_fast_assign( + tp_assign(order, order); + tp_assign(nr_requested, nr_requested); + tp_assign(nr_scanned, nr_scanned); + tp_assign(nr_taken, nr_taken); + tp_assign(nr_lumpy_taken, nr_lumpy_taken); + tp_assign(nr_lumpy_dirty, nr_lumpy_dirty); + tp_assign(nr_lumpy_failed, nr_lumpy_failed); + tp_assign(isolate_mode, isolate_mode); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) + tp_assign(file, file); +#endif + ), + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", +#else + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", +#endif + __entry->isolate_mode, + __entry->order, + __entry->nr_requested, + __entry->nr_scanned, + __entry->nr_taken, + __entry->nr_lumpy_taken, + __entry->nr_lumpy_dirty, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + __entry->nr_lumpy_failed) +#else + __entry->nr_lumpy_failed, + __entry->file) +#endif +) + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, +#endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + isolate_mode_t isolate_mode), +#else + isolate_mode_t isolate_mode, + int file), +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) +#else + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) +#endif + +) + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, +#endif +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + isolate_mode_t isolate_mode), +#else + isolate_mode_t isolate_mode, + int file), +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) +#else + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) +#endif + +) + +TRACE_EVENT(mm_vmscan_writepage, + + TP_PROTO(struct page *page, + int reclaim_flags), + + TP_ARGS(page, reclaim_flags), + + TP_STRUCT__entry( + __field(struct page *, page) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + tp_assign(page, page); + tp_assign(reclaim_flags, reclaim_flags); + ), + + TP_printk("page=%p pfn=%lu flags=%s", + __entry->page, + page_to_pfn(__entry->page), + show_reclaim_flags(__entry->reclaim_flags)) +) + +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, + + TP_PROTO(int nid, int zid, + unsigned long nr_scanned, unsigned long nr_reclaimed, + int priority, int reclaim_flags), + + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), + + TP_STRUCT__entry( + __field(int, nid) + __field(int, zid) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_reclaimed) + __field(int, priority) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + tp_assign(nid, nid); + tp_assign(zid, zid); + tp_assign(nr_scanned, nr_scanned); + tp_assign(nr_reclaimed, nr_reclaimed); + tp_assign(priority, priority); + tp_assign(reclaim_flags, reclaim_flags); + ), + + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", + __entry->nid, __entry->zid, + __entry->nr_scanned, __entry->nr_reclaimed, + __entry->priority, + show_reclaim_flags(__entry->reclaim_flags)) +) + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + +TRACE_EVENT(replace_swap_token, + TP_PROTO(struct mm_struct *old_mm, + struct mm_struct *new_mm), + + TP_ARGS(old_mm, new_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, old_mm) + __field(unsigned int, old_prio) + __field(struct mm_struct*, new_mm) + __field(unsigned int, new_prio) + ), + + TP_fast_assign( + tp_assign(old_mm, old_mm); + tp_assign(old_prio, old_mm ? old_mm->token_priority : 0); + tp_assign(new_mm, new_mm); + tp_assign(new_prio, new_mm->token_priority); + ), + + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", + __entry->old_mm, __entry->old_prio, + __entry->new_mm, __entry->new_prio) +) + +DECLARE_EVENT_CLASS(put_swap_token_template, + TP_PROTO(struct mm_struct *swap_token_mm), + + TP_ARGS(swap_token_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, swap_token_mm) + ), + + TP_fast_assign( + tp_assign(swap_token_mm, swap_token_mm); + ), + + TP_printk("token_mm=%p", __entry->swap_token_mm) +) + +DEFINE_EVENT(put_swap_token_template, put_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm) +) + +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm), + TP_CONDITION(swap_token_mm != NULL) +) + +TRACE_EVENT_CONDITION(update_swap_token_priority, + TP_PROTO(struct mm_struct *mm, + unsigned int old_prio, + struct mm_struct *swap_token_mm), + + TP_ARGS(mm, old_prio, swap_token_mm), + + TP_CONDITION(mm->token_priority != old_prio), + + TP_STRUCT__entry( + __field(struct mm_struct*, mm) + __field(unsigned int, old_prio) + __field(unsigned int, new_prio) + __field(struct mm_struct*, swap_token_mm) + __field(unsigned int, swap_token_prio) + ), + + TP_fast_assign( + tp_assign(mm, mm); + tp_assign(old_prio, old_prio); + tp_assign(new_prio, mm->token_priority); + tp_assign(swap_token_mm, swap_token_mm); + tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0); + ), + + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", + __entry->mm, __entry->old_prio, __entry->new_prio, + __entry->swap_token_mm, __entry->swap_token_prio) +) + +#endif + +#endif /* _TRACE_VMSCAN_H */ + +/* This part must be outside protection */ +#include "../../../probes/define_trace.h" diff --git a/instrumentation/events/mainline/asoc.h b/instrumentation/events/mainline/asoc.h new file mode 100644 index 0000000..ab26f8a --- /dev/null +++ b/instrumentation/events/mainline/asoc.h @@ -0,0 +1,330 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM asoc + +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ASOC_H + +#include +#include + +struct snd_soc_jack; +struct snd_soc_codec; +struct snd_soc_platform; +struct snd_soc_card; +struct snd_soc_dapm_widget; + +/* + * Log register events + */ +DECLARE_EVENT_CLASS(snd_soc_reg, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val), + + TP_STRUCT__entry( + __string( name, codec->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, codec->name); + __entry->id = codec->id; + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +); + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_preg, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val), + + TP_STRUCT__entry( + __string( name, platform->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, platform->name); + __entry->id = platform->id; + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +); + +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, + + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, + unsigned int val), + + TP_ARGS(platform, reg, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_card, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + __entry->val = val; + ), + + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) +); + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +); + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + ), + + TP_printk("card=%s", __get_str(name)) +); + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +); + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +); + +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val), + + TP_STRUCT__entry( + __string( name, w->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, w->name); + __entry->val = val; + ), + + TP_printk("widget=%s val=%d", __get_str(name), + (int)__entry->val) +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +TRACE_EVENT(snd_soc_dapm_walk_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, power_checks ) + __field( int, path_checks ) + __field( int, neighbour_checks ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + __entry->power_checks = card->dapm_stats.power_checks; + __entry->path_checks = card->dapm_stats.path_checks; + __entry->neighbour_checks = card->dapm_stats.neighbour_checks; + ), + + TP_printk("%s: checks %d power, %d path, %d neighbour", + __get_str(name), (int)__entry->power_checks, + (int)__entry->path_checks, (int)__entry->neighbour_checks) +); + +TRACE_EVENT(snd_soc_jack_irq, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + __assign_str(name, name); + ), + + TP_printk("%s", __get_str(name)) +); + +TRACE_EVENT(snd_soc_jack_report, + + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), + + TP_ARGS(jack, mask, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, mask ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, jack->jack->name); + __entry->mask = mask; + __entry->val = val; + ), + + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, + (int)__entry->mask) +); + +TRACE_EVENT(snd_soc_jack_notify, + + TP_PROTO(struct snd_soc_jack *jack, int val), + + TP_ARGS(jack, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, jack->jack->name); + __entry->val = val; + ), + + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) +); + +TRACE_EVENT(snd_soc_cache_sync, + + TP_PROTO(struct snd_soc_codec *codec, const char *type, + const char *status), + + TP_ARGS(codec, type, status), + + TP_STRUCT__entry( + __string( name, codec->name ) + __string( status, status ) + __string( type, type ) + __field( int, id ) + ), + + TP_fast_assign( + __assign_str(name, codec->name); + __assign_str(status, status); + __assign_str(type, type); + __entry->id = codec->id; + ), + + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), + (int)__entry->id, __get_str(type), __get_str(status)) +); + +#endif /* _TRACE_ASOC_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/ext3.h b/instrumentation/events/mainline/ext3.h new file mode 100644 index 0000000..7b53c05 --- /dev/null +++ b/instrumentation/events/mainline/ext3.h @@ -0,0 +1,864 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext3 + +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EXT3_H + +#include + +TRACE_EVENT(ext3_free_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( uid_t, uid ) + __field( gid_t, gid ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->uid = inode->i_uid; + __entry->gid = inode->i_gid; + __entry->blocks = inode->i_blocks; + ), + + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->uid, __entry->gid, + (unsigned long) __entry->blocks) +); + +TRACE_EVENT(ext3_request_inode, + TP_PROTO(struct inode *dir, int mode), + + TP_ARGS(dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + __entry->dev = dir->i_sb->s_dev; + __entry->dir = dir->i_ino; + __entry->mode = mode; + ), + + TP_printk("dev %d,%d dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->dir, __entry->mode) +); + +TRACE_EVENT(ext3_allocate_inode, + TP_PROTO(struct inode *inode, struct inode *dir, int mode), + + TP_ARGS(inode, dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->dir = dir->i_ino; + __entry->mode = mode; + ), + + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->dir, __entry->mode) +); + +TRACE_EVENT(ext3_evict_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, nlink ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->nlink = inode->i_nlink; + ), + + TP_printk("dev %d,%d ino %lu nlink %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->nlink) +); + +TRACE_EVENT(ext3_drop_inode, + TP_PROTO(struct inode *inode, int drop), + + TP_ARGS(inode, drop), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, drop ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->drop = drop; + ), + + TP_printk("dev %d,%d ino %lu drop %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->drop) +); + +TRACE_EVENT(ext3_mark_inode_dirty, + TP_PROTO(struct inode *inode, unsigned long IP), + + TP_ARGS(inode, IP), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field(unsigned long, ip ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->ip = IP; + ), + + TP_printk("dev %d,%d ino %lu caller %pF", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (void *)__entry->ip) +); + +TRACE_EVENT(ext3_write_begin, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), + + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, flags ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->flags = flags; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->flags) +); + +DECLARE_EVENT_CLASS(ext3__write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->copied) +); + +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +); + +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +); + +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied) +); + +DECLARE_EVENT_CLASS(ext3__page_op, + TP_PROTO(struct page *page), + + TP_ARGS(page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + __entry->index = page->index; + __entry->ino = page->mapping->host->i_ino; + __entry->dev = page->mapping->host->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu page_index %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, __entry->index) +); + +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_readpage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +DEFINE_EVENT(ext3__page_op, ext3_releasepage, + + TP_PROTO(struct page *page), + + TP_ARGS(page) +); + +TRACE_EVENT(ext3_invalidatepage, + TP_PROTO(struct page *page, unsigned long offset), + + TP_ARGS(page, offset), + + TP_STRUCT__entry( + __field( pgoff_t, index ) + __field( unsigned long, offset ) + __field( ino_t, ino ) + __field( dev_t, dev ) + + ), + + TP_fast_assign( + __entry->index = page->index; + __entry->offset = offset; + __entry->ino = page->mapping->host->i_ino; + __entry->dev = page->mapping->host->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->index, __entry->offset) +); + +TRACE_EVENT(ext3_discard_blocks, + TP_PROTO(struct super_block *sb, unsigned long blk, + unsigned long count), + + TP_ARGS(sb, blk, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, blk ) + __field( unsigned long, count ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->blk = blk; + __entry->count = count; + ), + + TP_printk("dev %d,%d blk %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->blk, __entry->count) +); + +TRACE_EVENT(ext3_request_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count), + + TP_ARGS(inode, goal, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->count = count; + __entry->goal = goal; + ), + + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->goal) +); + +TRACE_EVENT(ext3_allocate_blocks, + TP_PROTO(struct inode *inode, unsigned long goal, + unsigned long count, unsigned long block), + + TP_ARGS(inode, goal, count, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned long, block ) + __field( unsigned long, count ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->block = block; + __entry->count = count; + __entry->goal = goal; + ), + + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->count, __entry->block, + __entry->goal) +); + +TRACE_EVENT(ext3_free_blocks, + TP_PROTO(struct inode *inode, unsigned long block, + unsigned long count), + + TP_ARGS(inode, block, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( unsigned long, block ) + __field( unsigned long, count ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->block = block; + __entry->count = count; + ), + + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->block, __entry->count) +); + +TRACE_EVENT(ext3_sync_file_enter, + TP_PROTO(struct file *file, int datasync), + + TP_ARGS(file, datasync), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, parent ) + __field( int, datasync ) + ), + + TP_fast_assign( + struct dentry *dentry = file->f_path.dentry; + + __entry->dev = dentry->d_inode->i_sb->s_dev; + __entry->ino = dentry->d_inode->i_ino; + __entry->datasync = datasync; + __entry->parent = dentry->d_parent->d_inode->i_ino; + ), + + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long) __entry->parent, __entry->datasync) +); + +TRACE_EVENT(ext3_sync_file_exit, + TP_PROTO(struct inode *inode, int ret), + + TP_ARGS(inode, ret), + + TP_STRUCT__entry( + __field( int, ret ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->ret = ret; + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +); + +TRACE_EVENT(ext3_sync_fs, + TP_PROTO(struct super_block *sb, int wait), + + TP_ARGS(sb, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->wait = wait; + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +); + +TRACE_EVENT(ext3_rsv_window_add, + TP_PROTO(struct super_block *sb, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->start = rsv_node->rsv_window._rsv_start; + __entry->end = rsv_node->rsv_window._rsv_end; + ), + + TP_printk("dev %d,%d start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->start, __entry->end) +); + +TRACE_EVENT(ext3_discard_reservation, + TP_PROTO(struct inode *inode, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(inode, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->start = rsv_node->rsv_window._rsv_start; + __entry->end = rsv_node->rsv_window._rsv_end; + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long)__entry->ino, __entry->start, + __entry->end) +); + +TRACE_EVENT(ext3_alloc_new_reservation, + TP_PROTO(struct super_block *sb, unsigned long goal), + + TP_ARGS(sb, goal), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, goal ) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->goal = goal; + ), + + TP_printk("dev %d,%d goal %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->goal) +); + +TRACE_EVENT(ext3_reserved, + TP_PROTO(struct super_block *sb, unsigned long block, + struct ext3_reserve_window_node *rsv_node), + + TP_ARGS(sb, block, rsv_node), + + TP_STRUCT__entry( + __field( unsigned long, block ) + __field( unsigned long, start ) + __field( unsigned long, end ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->block = block; + __entry->start = rsv_node->rsv_window._rsv_start; + __entry->end = rsv_node->rsv_window._rsv_end; + __entry->dev = sb->s_dev; + ), + + TP_printk("dev %d,%d block %lu, start %lu end %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->block, __entry->start, __entry->end) +); + +TRACE_EVENT(ext3_forget, + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), + + TP_ARGS(inode, is_metadata, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( int, is_metadata ) + __field( unsigned long, block ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->is_metadata = is_metadata; + __entry->block = block; + ), + + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->mode, __entry->is_metadata, __entry->block) +); + +TRACE_EVENT(ext3_read_block_bitmap, + TP_PROTO(struct super_block *sb, unsigned int group), + + TP_ARGS(sb, group), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( __u32, group ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->group = group; + ), + + TP_printk("dev %d,%d group %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->group) +); + +TRACE_EVENT(ext3_direct_IO_enter, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), + + TP_ARGS(inode, offset, len, rw), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->pos = offset; + __entry->len = len; + __entry->rw = rw; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw) +); + +TRACE_EVENT(ext3_direct_IO_exit, + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, + int rw, int ret), + + TP_ARGS(inode, offset, len, rw, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( loff_t, pos ) + __field( unsigned long, len ) + __field( int, rw ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->pos = offset; + __entry->len = len; + __entry->rw = rw; + __entry->ret = ret; + ), + + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long) __entry->pos, __entry->len, + __entry->rw, __entry->ret) +); + +TRACE_EVENT(ext3_unlink_enter, + TP_PROTO(struct inode *parent, struct dentry *dentry), + + TP_ARGS(parent, dentry), + + TP_STRUCT__entry( + __field( ino_t, parent ) + __field( ino_t, ino ) + __field( loff_t, size ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->parent = parent->i_ino; + __entry->ino = dentry->d_inode->i_ino; + __entry->size = dentry->d_inode->i_size; + __entry->dev = dentry->d_inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu size %lld parent %ld", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + (unsigned long long)__entry->size, + (unsigned long) __entry->parent) +); + +TRACE_EVENT(ext3_unlink_exit, + TP_PROTO(struct dentry *dentry, int ret), + + TP_ARGS(dentry, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ino = dentry->d_inode->i_ino; + __entry->dev = dentry->d_inode->i_sb->s_dev; + __entry->ret = ret; + ), + + TP_printk("dev %d,%d ino %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->ret) +); + +DECLARE_EVENT_CLASS(ext3__truncate, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->blocks = inode->i_blocks; + ), + + TP_printk("dev %d,%d ino %lu blocks %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) +); + +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +); + +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, + + TP_PROTO(struct inode *inode), + + TP_ARGS(inode) +); + +TRACE_EVENT(ext3_get_blocks_enter, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long len, int create), + + TP_ARGS(inode, lblk, len, create), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, len ) + __field( int, create ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->lblk = lblk; + __entry->len = len; + __entry->create = create; + ), + + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->len, __entry->create) +); + +TRACE_EVENT(ext3_get_blocks_exit, + TP_PROTO(struct inode *inode, unsigned long lblk, + unsigned long pblk, unsigned long len, int ret), + + TP_ARGS(inode, lblk, pblk, len, ret), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + __field( unsigned long, lblk ) + __field( unsigned long, pblk ) + __field( unsigned long, len ) + __field( int, ret ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->lblk = lblk; + __entry->pblk = pblk; + __entry->len = len; + __entry->ret = ret; + ), + + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino, + __entry->lblk, __entry->pblk, + __entry->len, __entry->ret) +); + +TRACE_EVENT(ext3_load_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( ino_t, ino ) + __field( dev_t, dev ) + ), + + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +); + +#endif /* _TRACE_EXT3_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/fs_ext3.h b/instrumentation/events/mainline/fs_ext3.h new file mode 100644 index 0000000..76353e4 --- /dev/null +++ b/instrumentation/events/mainline/fs_ext3.h @@ -0,0 +1,1323 @@ +/* + * Written by Stephen C. Tweedie , 1999 + * + * Copyright 1998--1999 Red Hat corp --- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card at masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) + * + * from + * + * linux/include/linux/minix_fs.h + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include +#include +#include +#include +#include + +/* + * The second extended filesystem constants/structures + */ + +/* + * Define EXT3FS_DEBUG to produce debug messages + */ +#undef EXT3FS_DEBUG + +/* + * Define EXT3_RESERVATION to reserve data blocks for expanding files + */ +#define EXT3_DEFAULT_RESERVE_BLOCKS 8 +/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ +#define EXT3_MAX_RESERVE_BLOCKS 1027 +#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 + +/* + * Debug code + */ +#ifdef EXT3FS_DEBUG +#define ext3_debug(f, a...) \ + do { \ + printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ + __FILE__, __LINE__, __func__); \ + printk (KERN_DEBUG f, ## a); \ + } while (0) +#else +#define ext3_debug(f, a...) do {} while (0) +#endif + +/* + * Special inodes numbers + */ +#define EXT3_BAD_INO 1 /* Bad blocks inode */ +#define EXT3_ROOT_INO 2 /* Root inode */ +#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ +#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ +#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ +#define EXT3_JOURNAL_INO 8 /* Journal inode */ + +/* First non-reserved inode for old ext3 filesystems */ +#define EXT3_GOOD_OLD_FIRST_INO 11 + +/* + * Maximal count of links to a file + */ +#define EXT3_LINK_MAX 32000 + +/* + * Macro-instructions used to manage several block sizes + */ +#define EXT3_MIN_BLOCK_SIZE 1024 +#define EXT3_MAX_BLOCK_SIZE 65536 +#define EXT3_MIN_BLOCK_LOG_SIZE 10 +#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) +#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) +#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) +#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) +#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) +#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) + +/* + * Macro-instructions used to manage fragments + */ +#define EXT3_MIN_FRAG_SIZE 1024 +#define EXT3_MAX_FRAG_SIZE 4096 +#define EXT3_MIN_FRAG_LOG_SIZE 10 +#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) +#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) + +/* + * Structure of a blocks group descriptor + */ +struct ext3_group_desc +{ + __le32 bg_block_bitmap; /* Blocks bitmap block */ + __le32 bg_inode_bitmap; /* Inodes bitmap block */ + __le32 bg_inode_table; /* Inodes table block */ + __le16 bg_free_blocks_count; /* Free blocks count */ + __le16 bg_free_inodes_count; /* Free inodes count */ + __le16 bg_used_dirs_count; /* Directories count */ + __u16 bg_pad; + __le32 bg_reserved[3]; +}; + +/* + * Macro-instructions used to manage group descriptors + */ +#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) +#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) +#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) +#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) + +/* + * Constants relative to the data blocks + */ +#define EXT3_NDIR_BLOCKS 12 +#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS +#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1) +#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1) +#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1) + +/* + * Inode flags + */ +#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */ +#define EXT3_UNRM_FL 0x00000002 /* Undelete */ +#define EXT3_COMPR_FL 0x00000004 /* Compress file */ +#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */ +#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */ +#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */ +#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */ +#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */ +/* Reserved for compression usage... */ +#define EXT3_DIRTY_FL 0x00000100 +#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ +#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */ +#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */ +/* End compression flags --- maybe not all used */ +#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */ +#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ +#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ +#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ +#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ +#define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ +#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ + +#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ +#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ + +/* Flags that should be inherited by new inodes from their parent. */ +#define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ + EXT3_SYNC_FL | EXT3_NODUMP_FL |\ + EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\ + EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\ + EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL) + +/* Flags that are appropriate for regular files (all but dir-specific ones). */ +#define EXT3_REG_FLMASK (~(EXT3_DIRSYNC_FL | EXT3_TOPDIR_FL)) + +/* Flags that are appropriate for non-directories/regular files. */ +#define EXT3_OTHER_FLMASK (EXT3_NODUMP_FL | EXT3_NOATIME_FL) + +/* Mask out flags that are inappropriate for the given type of inode. */ +static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) +{ + if (S_ISDIR(mode)) + return flags; + else if (S_ISREG(mode)) + return flags & EXT3_REG_FLMASK; + else + return flags & EXT3_OTHER_FLMASK; +} + +/* Used to pass group descriptor data when online resize is done */ +struct ext3_new_group_input { + __u32 group; /* Group number for this data */ + __u32 block_bitmap; /* Absolute block number of block bitmap */ + __u32 inode_bitmap; /* Absolute block number of inode bitmap */ + __u32 inode_table; /* Absolute block number of inode table start */ + __u32 blocks_count; /* Total number of blocks in this group */ + __u16 reserved_blocks; /* Number of reserved blocks in this group */ + __u16 unused; +}; + +/* The struct ext3_new_group_input in kernel space, with free_blocks_count */ +struct ext3_new_group_data { + __u32 group; + __u32 block_bitmap; + __u32 inode_bitmap; + __u32 inode_table; + __u32 blocks_count; + __u16 reserved_blocks; + __u16 unused; + __u32 free_blocks_count; +}; + + +/* + * ioctl commands + */ +#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS +#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS +#define EXT3_IOC_GETVERSION _IOR('f', 3, long) +#define EXT3_IOC_SETVERSION _IOW('f', 4, long) +#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) +#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input) +#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION +#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION +#ifdef CONFIG_JBD_DEBUG +#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) +#endif +#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) +#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long) + +/* + * ioctl commands in 32 bit emulation + */ +#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS +#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS +#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) +#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) +#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) +#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) +#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) +#ifdef CONFIG_JBD_DEBUG +#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) +#endif +#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION +#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION + + +/* + * Mount options + */ +struct ext3_mount_options { + unsigned long s_mount_opt; + uid_t s_resuid; + gid_t s_resgid; + unsigned long s_commit_interval; +#ifdef CONFIG_QUOTA + int s_jquota_fmt; + char *s_qf_names[MAXQUOTAS]; +#endif +}; + +/* + * Structure of an inode on the disk + */ +struct ext3_inode { + __le16 i_mode; /* File mode */ + __le16 i_uid; /* Low 16 bits of Owner Uid */ + __le32 i_size; /* Size in bytes */ + __le32 i_atime; /* Access time */ + __le32 i_ctime; /* Creation time */ + __le32 i_mtime; /* Modification time */ + __le32 i_dtime; /* Deletion Time */ + __le16 i_gid; /* Low 16 bits of Group Id */ + __le16 i_links_count; /* Links count */ + __le32 i_blocks; /* Blocks count */ + __le32 i_flags; /* File flags */ + union { + struct { + __u32 l_i_reserved1; + } linux1; + struct { + __u32 h_i_translator; + } hurd1; + struct { + __u32 m_i_reserved1; + } masix1; + } osd1; /* OS dependent 1 */ + __le32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */ + __le32 i_generation; /* File version (for NFS) */ + __le32 i_file_acl; /* File ACL */ + __le32 i_dir_acl; /* Directory ACL */ + __le32 i_faddr; /* Fragment address */ + union { + struct { + __u8 l_i_frag; /* Fragment number */ + __u8 l_i_fsize; /* Fragment size */ + __u16 i_pad1; + __le16 l_i_uid_high; /* these 2 fields */ + __le16 l_i_gid_high; /* were reserved2[0] */ + __u32 l_i_reserved2; + } linux2; + struct { + __u8 h_i_frag; /* Fragment number */ + __u8 h_i_fsize; /* Fragment size */ + __u16 h_i_mode_high; + __u16 h_i_uid_high; + __u16 h_i_gid_high; + __u32 h_i_author; + } hurd2; + struct { + __u8 m_i_frag; /* Fragment number */ + __u8 m_i_fsize; /* Fragment size */ + __u16 m_pad1; + __u32 m_i_reserved2[2]; + } masix2; + } osd2; /* OS dependent 2 */ + __le16 i_extra_isize; + __le16 i_pad1; +}; + +#define i_size_high i_dir_acl + +#define i_reserved1 osd1.linux1.l_i_reserved1 +#define i_frag osd2.linux2.l_i_frag +#define i_fsize osd2.linux2.l_i_fsize +#define i_uid_low i_uid +#define i_gid_low i_gid +#define i_uid_high osd2.linux2.l_i_uid_high +#define i_gid_high osd2.linux2.l_i_gid_high +#define i_reserved2 osd2.linux2.l_i_reserved2 + +/* + * File system states + */ +#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */ +#define EXT3_ERROR_FS 0x0002 /* Errors detected */ +#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */ + +/* + * Misc. filesystem flags + */ +#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ +#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ +#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ + +/* + * Mount flags + */ +#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */ +/* EXT3_MOUNT_OLDALLOC was there */ +#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */ +#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */ +#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ +#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ +#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ +#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ +#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ +#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */ +#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ +#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ +#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ +#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ +#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ +#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ +#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ +#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ +#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ +#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ +#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ +#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ +#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write + * error in ordered mode */ + +/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ +#ifndef _LINUX_EXT2_FS_H +#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt +#define set_opt(o, opt) o |= EXT3_MOUNT_##opt +#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ + EXT3_MOUNT_##opt) +#else +#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD +#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT +#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS +#endif + +#define ext3_set_bit __set_bit_le +#define ext3_set_bit_atomic ext2_set_bit_atomic +#define ext3_clear_bit __clear_bit_le +#define ext3_clear_bit_atomic ext2_clear_bit_atomic +#define ext3_test_bit test_bit_le +#define ext3_find_next_zero_bit find_next_zero_bit_le + +/* + * Maximal mount counts between two filesystem checks + */ +#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ +#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */ + +/* + * Behaviour when detecting errors + */ +#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */ +#define EXT3_ERRORS_RO 2 /* Remount fs read-only */ +#define EXT3_ERRORS_PANIC 3 /* Panic */ +#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE + +/* + * Structure of the super block + */ +struct ext3_super_block { +/*00*/ __le32 s_inodes_count; /* Inodes count */ + __le32 s_blocks_count; /* Blocks count */ + __le32 s_r_blocks_count; /* Reserved blocks count */ + __le32 s_free_blocks_count; /* Free blocks count */ +/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ + __le32 s_first_data_block; /* First Data Block */ + __le32 s_log_block_size; /* Block size */ + __le32 s_log_frag_size; /* Fragment size */ +/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ + __le32 s_frags_per_group; /* # Fragments per group */ + __le32 s_inodes_per_group; /* # Inodes per group */ + __le32 s_mtime; /* Mount time */ +/*30*/ __le32 s_wtime; /* Write time */ + __le16 s_mnt_count; /* Mount count */ + __le16 s_max_mnt_count; /* Maximal mount count */ + __le16 s_magic; /* Magic signature */ + __le16 s_state; /* File system state */ + __le16 s_errors; /* Behaviour when detecting errors */ + __le16 s_minor_rev_level; /* minor revision level */ +/*40*/ __le32 s_lastcheck; /* time of last check */ + __le32 s_checkinterval; /* max. time between checks */ + __le32 s_creator_os; /* OS */ + __le32 s_rev_level; /* Revision level */ +/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ + __le16 s_def_resgid; /* Default gid for reserved blocks */ + /* + * These fields are for EXT3_DYNAMIC_REV superblocks only. + * + * Note: the difference between the compatible feature set and + * the incompatible feature set is that if there is a bit set + * in the incompatible feature set that the kernel doesn't + * know about, it should refuse to mount the filesystem. + * + * e2fsck's requirements are more strict; if it doesn't know + * about a feature in either the compatible or incompatible + * feature set, it must abort and not try to meddle with + * things it doesn't understand... + */ + __le32 s_first_ino; /* First non-reserved inode */ + __le16 s_inode_size; /* size of inode structure */ + __le16 s_block_group_nr; /* block group # of this superblock */ + __le32 s_feature_compat; /* compatible feature set */ +/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ + __le32 s_feature_ro_compat; /* readonly-compatible feature set */ +/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ +/*78*/ char s_volume_name[16]; /* volume name */ +/*88*/ char s_last_mounted[64]; /* directory where last mounted */ +/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ + /* + * Performance hints. Directory preallocation should only + * happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on. + */ + __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ + __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ + __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ + /* + * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. + */ +/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ +/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ + __le32 s_journal_dev; /* device number of journal file */ + __le32 s_last_orphan; /* start of list of inodes to delete */ + __le32 s_hash_seed[4]; /* HTREE hash seed */ + __u8 s_def_hash_version; /* Default hash version to use */ + __u8 s_reserved_char_pad; + __u16 s_reserved_word_pad; + __le32 s_default_mount_opts; + __le32 s_first_meta_bg; /* First metablock block group */ + __le32 s_mkfs_time; /* When the filesystem was created */ + __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ + /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ +/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ + __le32 s_r_blocks_count_hi; /* Reserved blocks count */ + __le32 s_free_blocks_count_hi; /* Free blocks count */ + __le16 s_min_extra_isize; /* All inodes have at least # bytes */ + __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ + __le32 s_flags; /* Miscellaneous flags */ + __le16 s_raid_stride; /* RAID stride */ + __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ + __le64 s_mmp_block; /* Block for multi-mount protection */ + __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ + __u8 s_log_groups_per_flex; /* FLEX_BG group size */ + __u8 s_reserved_char_pad2; + __le16 s_reserved_pad; + __u32 s_reserved[162]; /* Padding to the end of the block */ +}; + +/* data type for block offset of block group */ +typedef int ext3_grpblk_t; + +/* data type for filesystem-wide blocks number */ +typedef unsigned long ext3_fsblk_t; + +#define E3FSBLK "%lu" + +struct ext3_reserve_window { + ext3_fsblk_t _rsv_start; /* First byte reserved */ + ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ +}; + +struct ext3_reserve_window_node { + struct rb_node rsv_node; + __u32 rsv_goal_size; + __u32 rsv_alloc_hit; + struct ext3_reserve_window rsv_window; +}; + +struct ext3_block_alloc_info { + /* information about reservation window */ + struct ext3_reserve_window_node rsv_window_node; + /* + * was i_next_alloc_block in ext3_inode_info + * is the logical (file-relative) number of the + * most-recently-allocated block in this file. + * We use this for detecting linearly ascending allocation requests. + */ + __u32 last_alloc_logical_block; + /* + * Was i_next_alloc_goal in ext3_inode_info + * is the *physical* companion to i_next_alloc_block. + * it the physical block number of the block which was most-recentl + * allocated to this file. This give us the goal (target) for the next + * allocation when we detect linearly ascending requests. + */ + ext3_fsblk_t last_alloc_physical_block; +}; + +#define rsv_start rsv_window._rsv_start +#define rsv_end rsv_window._rsv_end + +/* + * third extended file system inode data in memory + */ +struct ext3_inode_info { + __le32 i_data[15]; /* unconverted */ + __u32 i_flags; +#ifdef EXT3_FRAGMENTS + __u32 i_faddr; + __u8 i_frag_no; + __u8 i_frag_size; +#endif + ext3_fsblk_t i_file_acl; + __u32 i_dir_acl; + __u32 i_dtime; + + /* + * i_block_group is the number of the block group which contains + * this file's inode. Constant across the lifetime of the inode, + * it is ued for making block allocation decisions - we try to + * place a file's data blocks near its inode block, and new inodes + * near to their parent directory's inode. + */ + __u32 i_block_group; + unsigned long i_state_flags; /* Dynamic state flags for ext3 */ + + /* block reservation info */ + struct ext3_block_alloc_info *i_block_alloc_info; + + __u32 i_dir_start_lookup; +#ifdef CONFIG_EXT3_FS_XATTR + /* + * Extended attributes can be read independently of the main file + * data. Taking i_mutex even when reading would cause contention + * between readers of EAs and writers of regular file data, so + * instead we synchronize on xattr_sem when reading or changing + * EAs. + */ + struct rw_semaphore xattr_sem; +#endif + + struct list_head i_orphan; /* unlinked but open inodes */ + + /* + * i_disksize keeps track of what the inode size is ON DISK, not + * in memory. During truncate, i_size is set to the new size by + * the VFS prior to calling ext3_truncate(), but the filesystem won't + * set i_disksize to 0 until the truncate is actually under way. + * + * The intent is that i_disksize always represents the blocks which + * are used by this file. This allows recovery to restart truncate + * on orphans if we crash during truncate. We actually write i_disksize + * into the on-disk inode when writing inodes out, instead of i_size. + * + * The only time when i_disksize and i_size may be different is when + * a truncate is in progress. The only things which change i_disksize + * are ext3_get_block (growth) and ext3_truncate (shrinkth). + */ + loff_t i_disksize; + + /* on-disk additional length */ + __u16 i_extra_isize; + + /* + * truncate_mutex is for serialising ext3_truncate() against + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's + * data tree are chopped off during truncate. We can't do that in + * ext3 because whenever we perform intermediate commits during + * truncate, the inode and all the metadata blocks *must* be in a + * consistent state which allows truncation of the orphans to restart + * during recovery. Hence we must fix the get_block-vs-truncate race + * by other means, so we have truncate_mutex. + */ + struct mutex truncate_mutex; + + /* + * Transactions that contain inode's metadata needed to complete + * fsync and fdatasync, respectively. + */ + atomic_t i_sync_tid; + atomic_t i_datasync_tid; + + struct inode vfs_inode; +}; + +/* + * third extended-fs super-block data in memory + */ +struct ext3_sb_info { + unsigned long s_frag_size; /* Size of a fragment in bytes */ + unsigned long s_frags_per_block;/* Number of fragments per block */ + unsigned long s_inodes_per_block;/* Number of inodes per block */ + unsigned long s_frags_per_group;/* Number of fragments in a group */ + unsigned long s_blocks_per_group;/* Number of blocks in a group */ + unsigned long s_inodes_per_group;/* Number of inodes in a group */ + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ + unsigned long s_gdb_count; /* Number of group descriptor blocks */ + unsigned long s_desc_per_block; /* Number of group descriptors per block */ + unsigned long s_groups_count; /* Number of groups in the fs */ + unsigned long s_overhead_last; /* Last calculated overhead */ + unsigned long s_blocks_last; /* Last seen block count */ + struct buffer_head * s_sbh; /* Buffer containing the super block */ + struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ + struct buffer_head ** s_group_desc; + unsigned long s_mount_opt; + ext3_fsblk_t s_sb_block; + uid_t s_resuid; + gid_t s_resgid; + unsigned short s_mount_state; + unsigned short s_pad; + int s_addr_per_block_bits; + int s_desc_per_block_bits; + int s_inode_size; + int s_first_ino; + spinlock_t s_next_gen_lock; + u32 s_next_generation; + u32 s_hash_seed[4]; + int s_def_hash_version; + int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ + struct percpu_counter s_freeblocks_counter; + struct percpu_counter s_freeinodes_counter; + struct percpu_counter s_dirs_counter; + struct blockgroup_lock *s_blockgroup_lock; + + /* root of the per fs reservation window tree */ + spinlock_t s_rsv_window_lock; + struct rb_root s_rsv_window_root; + struct ext3_reserve_window_node s_rsv_window_head; + + /* Journaling */ + struct inode * s_journal_inode; + struct journal_s * s_journal; + struct list_head s_orphan; + struct mutex s_orphan_lock; + struct mutex s_resize_lock; + unsigned long s_commit_interval; + struct block_device *journal_bdev; +#ifdef CONFIG_QUOTA + char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ + int s_jquota_fmt; /* Format of quota to use */ +#endif +}; + +static inline spinlock_t * +sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) +{ + return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); +} + +static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} +static inline struct ext3_inode_info *EXT3_I(struct inode *inode) +{ + return container_of(inode, struct ext3_inode_info, vfs_inode); +} + +static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) +{ + return ino == EXT3_ROOT_INO || + ino == EXT3_JOURNAL_INO || + ino == EXT3_RESIZE_INO || + (ino >= EXT3_FIRST_INO(sb) && + ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); +} + +/* + * Inode dynamic state flags + */ +enum { + EXT3_STATE_JDATA, /* journaled data exists */ + EXT3_STATE_NEW, /* inode is newly created */ + EXT3_STATE_XATTR, /* has in-inode xattrs */ + EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ +}; + +static inline int ext3_test_inode_state(struct inode *inode, int bit) +{ + return test_bit(bit, &EXT3_I(inode)->i_state_flags); +} + +static inline void ext3_set_inode_state(struct inode *inode, int bit) +{ + set_bit(bit, &EXT3_I(inode)->i_state_flags); +} + +static inline void ext3_clear_inode_state(struct inode *inode, int bit) +{ + clear_bit(bit, &EXT3_I(inode)->i_state_flags); +} + +#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime + +/* + * Codes for operating systems + */ +#define EXT3_OS_LINUX 0 +#define EXT3_OS_HURD 1 +#define EXT3_OS_MASIX 2 +#define EXT3_OS_FREEBSD 3 +#define EXT3_OS_LITES 4 + +/* + * Revision levels + */ +#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */ +#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ + +#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV +#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV + +#define EXT3_GOOD_OLD_INODE_SIZE 128 + +/* + * Feature set definitions + */ + +#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \ + ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) +#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \ + ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) +#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \ + ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) +#define EXT3_SET_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) +#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) +#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) +#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) +#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) +#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \ + EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) + +#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001 +#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008 +#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010 +#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020 + +#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 + +#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001 +#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ +#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 + +#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR +#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ + EXT3_FEATURE_INCOMPAT_META_BG) +#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) + +/* + * Default values for user and/or group using reserved blocks + */ +#define EXT3_DEF_RESUID 0 +#define EXT3_DEF_RESGID 0 + +/* + * Default mount options + */ +#define EXT3_DEFM_DEBUG 0x0001 +#define EXT3_DEFM_BSDGROUPS 0x0002 +#define EXT3_DEFM_XATTR_USER 0x0004 +#define EXT3_DEFM_ACL 0x0008 +#define EXT3_DEFM_UID16 0x0010 +#define EXT3_DEFM_JMODE 0x0060 +#define EXT3_DEFM_JMODE_DATA 0x0020 +#define EXT3_DEFM_JMODE_ORDERED 0x0040 +#define EXT3_DEFM_JMODE_WBACK 0x0060 + +/* + * Structure of a directory entry + */ +#define EXT3_NAME_LEN 255 + +struct ext3_dir_entry { + __le32 inode; /* Inode number */ + __le16 rec_len; /* Directory entry length */ + __le16 name_len; /* Name length */ + char name[EXT3_NAME_LEN]; /* File name */ +}; + +/* + * The new version of the directory entry. Since EXT3 structures are + * stored in intel byte order, and the name_len field could never be + * bigger than 255 chars, it's safe to reclaim the extra byte for the + * file_type field. + */ +struct ext3_dir_entry_2 { + __le32 inode; /* Inode number */ + __le16 rec_len; /* Directory entry length */ + __u8 name_len; /* Name length */ + __u8 file_type; + char name[EXT3_NAME_LEN]; /* File name */ +}; + +/* + * Ext3 directory file types. Only the low 3 bits are used. The + * other bits are reserved for now. + */ +#define EXT3_FT_UNKNOWN 0 +#define EXT3_FT_REG_FILE 1 +#define EXT3_FT_DIR 2 +#define EXT3_FT_CHRDEV 3 +#define EXT3_FT_BLKDEV 4 +#define EXT3_FT_FIFO 5 +#define EXT3_FT_SOCK 6 +#define EXT3_FT_SYMLINK 7 + +#define EXT3_FT_MAX 8 + +/* + * EXT3_DIR_PAD defines the directory entries boundaries + * + * NOTE: It must be a multiple of 4 + */ +#define EXT3_DIR_PAD 4 +#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) +#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ + ~EXT3_DIR_ROUND) +#define EXT3_MAX_REC_LEN ((1<<16)-1) + +/* + * Tests against MAX_REC_LEN etc were put in place for 64k block + * sizes; if that is not possible on this arch, we can skip + * those tests and speed things up. + */ +static inline unsigned ext3_rec_len_from_disk(__le16 dlen) +{ + unsigned len = le16_to_cpu(dlen); + +#if (PAGE_CACHE_SIZE >= 65536) + if (len == EXT3_MAX_REC_LEN) + return 1 << 16; +#endif + return len; +} + +static inline __le16 ext3_rec_len_to_disk(unsigned len) +{ +#if (PAGE_CACHE_SIZE >= 65536) + if (len == (1 << 16)) + return cpu_to_le16(EXT3_MAX_REC_LEN); + else if (len > (1 << 16)) + BUG(); +#endif + return cpu_to_le16(len); +} + +/* + * Hash Tree Directory indexing + * (c) Daniel Phillips, 2001 + */ + +#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ + EXT3_FEATURE_COMPAT_DIR_INDEX) && \ + (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) +#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) +#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) + +/* Legal values for the dx_root hash_version field: */ + +#define DX_HASH_LEGACY 0 +#define DX_HASH_HALF_MD4 1 +#define DX_HASH_TEA 2 +#define DX_HASH_LEGACY_UNSIGNED 3 +#define DX_HASH_HALF_MD4_UNSIGNED 4 +#define DX_HASH_TEA_UNSIGNED 5 + +/* hash info structure used by the directory hash */ +struct dx_hash_info +{ + u32 hash; + u32 minor_hash; + int hash_version; + u32 *seed; +}; + +#define EXT3_HTREE_EOF 0x7fffffff + +/* + * Control parameters used by ext3_htree_next_block + */ +#define HASH_NB_ALWAYS 1 + + +/* + * Describe an inode's exact location on disk and in memory + */ +struct ext3_iloc +{ + struct buffer_head *bh; + unsigned long offset; + unsigned long block_group; +}; + +static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc) +{ + return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset); +} + +/* + * This structure is stuffed into the struct file's private_data field + * for directories. It is where we put information so that we can do + * readdir operations in hash tree order. + */ +struct dir_private_info { + struct rb_root root; + struct rb_node *curr_node; + struct fname *extra_fname; + loff_t last_pos; + __u32 curr_hash; + __u32 curr_minor_hash; + __u32 next_hash; +}; + +/* calculate the first block number of the group */ +static inline ext3_fsblk_t +ext3_group_first_block_no(struct super_block *sb, unsigned long group_no) +{ + return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) + + le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); +} + +/* + * Special error return code only used by dx_probe() and its callers. + */ +#define ERR_BAD_DX_DIR -75000 + +/* + * Function prototypes + */ + +/* + * Ok, these declarations are also in but none of the + * ext3 source programs needs to include it so they are duplicated here. + */ +# define NORET_TYPE /**/ +# define ATTRIB_NORET __attribute__((noreturn)) +# define NORET_AND noreturn, + +/* balloc.c */ +extern int ext3_bg_has_super(struct super_block *sb, int group); +extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); +extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode, + ext3_fsblk_t goal, int *errp); +extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode, + ext3_fsblk_t goal, unsigned long *count, int *errp); +extern void ext3_free_blocks (handle_t *handle, struct inode *inode, + ext3_fsblk_t block, unsigned long count); +extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb, + ext3_fsblk_t block, unsigned long count, + unsigned long *pdquot_freed_blocks); +extern ext3_fsblk_t ext3_count_free_blocks (struct super_block *); +extern void ext3_check_blocks_bitmap (struct super_block *); +extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, + unsigned int block_group, + struct buffer_head ** bh); +extern int ext3_should_retry_alloc(struct super_block *sb, int *retries); +extern void ext3_init_block_alloc_info(struct inode *); +extern void ext3_rsv_window_add(struct super_block *sb, struct ext3_reserve_window_node *rsv); +extern int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range); + +/* dir.c */ +extern int ext3_check_dir_entry(const char *, struct inode *, + struct ext3_dir_entry_2 *, + struct buffer_head *, unsigned long); +extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, + __u32 minor_hash, + struct ext3_dir_entry_2 *dirent); +extern void ext3_htree_free_dir_info(struct dir_private_info *p); + +/* fsync.c */ +extern int ext3_sync_file(struct file *, loff_t, loff_t, int); + +/* hash.c */ +extern int ext3fs_dirhash(const char *name, int len, struct + dx_hash_info *hinfo); + +/* ialloc.c */ +extern struct inode * ext3_new_inode (handle_t *, struct inode *, + const struct qstr *, umode_t); +extern void ext3_free_inode (handle_t *, struct inode *); +extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); +extern unsigned long ext3_count_free_inodes (struct super_block *); +extern unsigned long ext3_count_dirs (struct super_block *); +extern void ext3_check_inodes_bitmap (struct super_block *); +extern unsigned long ext3_count_free (struct buffer_head *, unsigned); + + +/* inode.c */ +int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, + struct buffer_head *bh, ext3_fsblk_t blocknr); +struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); +struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); +int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, + int create); + +extern struct inode *ext3_iget(struct super_block *, unsigned long); +extern int ext3_write_inode (struct inode *, struct writeback_control *); +extern int ext3_setattr (struct dentry *, struct iattr *); +extern void ext3_evict_inode (struct inode *); +extern int ext3_sync_inode (handle_t *, struct inode *); +extern void ext3_discard_reservation (struct inode *); +extern void ext3_dirty_inode(struct inode *, int); +extern int ext3_change_inode_journal_flag(struct inode *, int); +extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); +extern int ext3_can_truncate(struct inode *inode); +extern void ext3_truncate(struct inode *inode); +extern void ext3_set_inode_flags(struct inode *); +extern void ext3_get_inode_flags(struct ext3_inode_info *); +extern void ext3_set_aops(struct inode *inode); +extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len); + +/* ioctl.c */ +extern long ext3_ioctl(struct file *, unsigned int, unsigned long); +extern long ext3_compat_ioctl(struct file *, unsigned int, unsigned long); + +/* namei.c */ +extern int ext3_orphan_add(handle_t *, struct inode *); +extern int ext3_orphan_del(handle_t *, struct inode *); +extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, + __u32 start_minor_hash, __u32 *next_hash); + +/* resize.c */ +extern int ext3_group_add(struct super_block *sb, + struct ext3_new_group_data *input); +extern int ext3_group_extend(struct super_block *sb, + struct ext3_super_block *es, + ext3_fsblk_t n_blocks_count); + +/* super.c */ +extern __printf(3, 4) +void ext3_error(struct super_block *, const char *, const char *, ...); +extern void __ext3_std_error (struct super_block *, const char *, int); +extern __printf(3, 4) +void ext3_abort(struct super_block *, const char *, const char *, ...); +extern __printf(3, 4) +void ext3_warning(struct super_block *, const char *, const char *, ...); +extern __printf(3, 4) +void ext3_msg(struct super_block *, const char *, const char *, ...); +extern void ext3_update_dynamic_rev (struct super_block *sb); + +#define ext3_std_error(sb, errno) \ +do { \ + if ((errno)) \ + __ext3_std_error((sb), __func__, (errno)); \ +} while (0) + +/* + * Inodes and files operations + */ + +/* dir.c */ +extern const struct file_operations ext3_dir_operations; + +/* file.c */ +extern const struct inode_operations ext3_file_inode_operations; +extern const struct file_operations ext3_file_operations; + +/* namei.c */ +extern const struct inode_operations ext3_dir_inode_operations; +extern const struct inode_operations ext3_special_inode_operations; + +/* symlink.c */ +extern const struct inode_operations ext3_symlink_inode_operations; +extern const struct inode_operations ext3_fast_symlink_inode_operations; + +#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) + +/* Define the number of blocks we need to account to a transaction to + * modify one block of data. + * + * We may have to touch one inode, one bitmap buffer, up to three + * indirection blocks, the group and superblock summaries, and the data + * block to complete the transaction. */ + +#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U + +/* Extended attribute operations touch at most two data buffers, + * two bitmap buffers, and two group summaries, in addition to the inode + * and the superblock, which are already accounted for. */ + +#define EXT3_XATTR_TRANS_BLOCKS 6U + +/* Define the minimum size for a transaction which modifies data. This + * needs to take into account the fact that we may end up modifying two + * quota files too (one for the group, one for the user quota). The + * superblock only gets updated once, of course, so don't bother + * counting that again for the quota updates. */ + +#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ + EXT3_XATTR_TRANS_BLOCKS - 2 + \ + EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) + +/* Delete operations potentially hit one directory's namespace plus an + * entire inode, plus arbitrary amounts of bitmap/indirection data. Be + * generous. We can grow the delete transaction later if necessary. */ + +#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) + +/* Define an arbitrary limit for the amount of data we will anticipate + * writing to any given transaction. For unbounded transactions such as + * write(2) and truncate(2) we can write more than this, but we always + * start off at the maximum transaction size and grow the transaction + * optimistically as we go. */ + +#define EXT3_MAX_TRANS_DATA 64U + +/* We break up a large truncate or write transaction once the handle's + * buffer credits gets this low, we need either to extend the + * transaction or to start a new one. Reserve enough space here for + * inode, bitmap, superblock, group and indirection updates for at least + * one block, plus two quota updates. Quota allocations are not + * needed. */ + +#define EXT3_RESERVE_TRANS_BLOCKS 12U + +#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 + +#ifdef CONFIG_QUOTA +/* Amount of blocks needed for quota update - we know that the structure was + * allocated so we need to update only inode+data */ +#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) +/* Amount of blocks needed for quota insert/delete - we do some block writes + * but inode, sb and group updates are done only once */ +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) +#else +#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 +#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 +#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 +#endif +#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) + +int +ext3_mark_iloc_dirty(handle_t *handle, + struct inode *inode, + struct ext3_iloc *iloc); + +/* + * On success, We end up with an outstanding reference count against + * iloc->bh. This _must_ be cleaned up later. + */ + +int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, + struct ext3_iloc *iloc); + +int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); + +/* + * Wrapper functions with which ext3 calls into JBD. The intent here is + * to allow these to be turned into appropriate stubs so ext3 can control + * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't + * been done yet. + */ + +static inline void ext3_journal_release_buffer(handle_t *handle, + struct buffer_head *bh) +{ + journal_release_buffer(handle, bh); +} + +void ext3_journal_abort_handle(const char *caller, const char *err_fn, + struct buffer_head *bh, handle_t *handle, int err); + +int __ext3_journal_get_undo_access(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_get_write_access(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_forget(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_revoke(const char *where, handle_t *handle, + unsigned long blocknr, struct buffer_head *bh); + +int __ext3_journal_get_create_access(const char *where, + handle_t *handle, struct buffer_head *bh); + +int __ext3_journal_dirty_metadata(const char *where, + handle_t *handle, struct buffer_head *bh); + +#define ext3_journal_get_undo_access(handle, bh) \ + __ext3_journal_get_undo_access(__func__, (handle), (bh)) +#define ext3_journal_get_write_access(handle, bh) \ + __ext3_journal_get_write_access(__func__, (handle), (bh)) +#define ext3_journal_revoke(handle, blocknr, bh) \ + __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) +#define ext3_journal_get_create_access(handle, bh) \ + __ext3_journal_get_create_access(__func__, (handle), (bh)) +#define ext3_journal_dirty_metadata(handle, bh) \ + __ext3_journal_dirty_metadata(__func__, (handle), (bh)) +#define ext3_journal_forget(handle, bh) \ + __ext3_journal_forget(__func__, (handle), (bh)) + +int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); + +handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); +int __ext3_journal_stop(const char *where, handle_t *handle); + +static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) +{ + return ext3_journal_start_sb(inode->i_sb, nblocks); +} + +#define ext3_journal_stop(handle) \ + __ext3_journal_stop(__func__, (handle)) + +static inline handle_t *ext3_journal_current_handle(void) +{ + return journal_current_handle(); +} + +static inline int ext3_journal_extend(handle_t *handle, int nblocks) +{ + return journal_extend(handle, nblocks); +} + +static inline int ext3_journal_restart(handle_t *handle, int nblocks) +{ + return journal_restart(handle, nblocks); +} + +static inline int ext3_journal_blocks_per_page(struct inode *inode) +{ + return journal_blocks_per_page(inode); +} + +static inline int ext3_journal_force_commit(journal_t *journal) +{ + return journal_force_commit(journal); +} + +/* super.c */ +int ext3_force_commit(struct super_block *sb); + +static inline int ext3_should_journal_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 1; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) + return 1; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 1; + return 0; +} + +static inline int ext3_should_order_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) + return 1; + return 0; +} + +static inline int ext3_should_writeback_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) + return 1; + return 0; +} + +#include + diff --git a/instrumentation/events/mainline/gpio.h b/instrumentation/events/mainline/gpio.h new file mode 100644 index 0000000..927a8ad --- /dev/null +++ b/instrumentation/events/mainline/gpio.h @@ -0,0 +1,56 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM gpio + +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_GPIO_H + +#include + +TRACE_EVENT(gpio_direction, + + TP_PROTO(unsigned gpio, int in, int err), + + TP_ARGS(gpio, in, err), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, in) + __field(int, err) + ), + + TP_fast_assign( + __entry->gpio = gpio; + __entry->in = in; + __entry->err = err; + ), + + TP_printk("%u %3s (%d)", __entry->gpio, + __entry->in ? "in" : "out", __entry->err) +); + +TRACE_EVENT(gpio_value, + + TP_PROTO(unsigned gpio, int get, int value), + + TP_ARGS(gpio, get, value), + + TP_STRUCT__entry( + __field(unsigned, gpio) + __field(int, get) + __field(int, value) + ), + + TP_fast_assign( + __entry->gpio = gpio; + __entry->get = get; + __entry->value = value; + ), + + TP_printk("%u %3s %d", __entry->gpio, + __entry->get ? "get" : "set", __entry->value) +); + +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/jbd.h b/instrumentation/events/mainline/jbd.h new file mode 100644 index 0000000..aff64d8 --- /dev/null +++ b/instrumentation/events/mainline/jbd.h @@ -0,0 +1,203 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd + +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD_H + +#include +#include + +TRACE_EVENT(jbd_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->result = result; + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->result) +); + +DECLARE_EVENT_CLASS(jbd_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +DEFINE_EVENT(jbd_commit, jbd_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd_commit, jbd_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd_commit, jbd_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +TRACE_EVENT(jbd_drop_transaction, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +TRACE_EVENT(jbd_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + __entry->head = journal->j_tail_sequence; + ), + + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +); + +TRACE_EVENT(jbd_do_submit_data, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +TRACE_EVENT(jbd_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->tail_sequence = journal->j_tail_sequence; + __entry->first_tid = first_tid; + __entry->block_nr = block_nr; + __entry->freed = freed; + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +); + +TRACE_EVENT(jbd_update_superblock_end, + TP_PROTO(journal_t *journal, int wait), + + TP_ARGS(journal, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->wait = wait; + ), + + TP_printk("dev %d,%d wait %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->wait) +); + +#endif /* _TRACE_JBD_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/jbd2.h b/instrumentation/events/mainline/jbd2.h new file mode 100644 index 0000000..7596441 --- /dev/null +++ b/instrumentation/events/mainline/jbd2.h @@ -0,0 +1,235 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd2 + +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD2_H + +#include +#include + +struct transaction_chp_stats_s; +struct transaction_run_stats_s; + +TRACE_EVENT(jbd2_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->result = result; + ), + + TP_printk("dev %d,%d result %d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) +); + +DECLARE_EVENT_CLASS(jbd2_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %d,%d transaction %d sync %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit) +); + +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + +TRACE_EVENT(jbd2_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + __entry->head = journal->j_tail_sequence; + ), + + TP_printk("dev %d,%d transaction %d sync %d head %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->transaction, __entry->sync_commit, __entry->head) +); + +TRACE_EVENT(jbd2_submit_inode_data, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + ), + + TP_printk("dev %d,%d ino %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + (unsigned long) __entry->ino) +); + +TRACE_EVENT(jbd2_run_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_run_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, wait ) + __field( unsigned long, running ) + __field( unsigned long, locked ) + __field( unsigned long, flushing ) + __field( unsigned long, logging ) + __field( __u32, handle_count ) + __field( __u32, blocks ) + __field( __u32, blocks_logged ) + ), + + TP_fast_assign( + __entry->dev = dev; + __entry->tid = tid; + __entry->wait = stats->rs_wait; + __entry->running = stats->rs_running; + __entry->locked = stats->rs_locked; + __entry->flushing = stats->rs_flushing; + __entry->logging = stats->rs_logging; + __entry->handle_count = stats->rs_handle_count; + __entry->blocks = stats->rs_blocks; + __entry->blocks_logged = stats->rs_blocks_logged; + ), + + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " + "logging %u handle_count %u blocks %u blocks_logged %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->wait), + jiffies_to_msecs(__entry->running), + jiffies_to_msecs(__entry->locked), + jiffies_to_msecs(__entry->flushing), + jiffies_to_msecs(__entry->logging), + __entry->handle_count, __entry->blocks, + __entry->blocks_logged) +); + +TRACE_EVENT(jbd2_checkpoint_stats, + TP_PROTO(dev_t dev, unsigned long tid, + struct transaction_chp_stats_s *stats), + + TP_ARGS(dev, tid, stats), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( unsigned long, tid ) + __field( unsigned long, chp_time ) + __field( __u32, forced_to_close ) + __field( __u32, written ) + __field( __u32, dropped ) + ), + + TP_fast_assign( + __entry->dev = dev; + __entry->tid = tid; + __entry->chp_time = stats->cs_chp_time; + __entry->forced_to_close= stats->cs_forced_to_close; + __entry->written = stats->cs_written; + __entry->dropped = stats->cs_dropped; + ), + + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " + "written %u dropped %u", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, + jiffies_to_msecs(__entry->chp_time), + __entry->forced_to_close, __entry->written, __entry->dropped) +); + +TRACE_EVENT(jbd2_cleanup_journal_tail, + + TP_PROTO(journal_t *journal, tid_t first_tid, + unsigned long block_nr, unsigned long freed), + + TP_ARGS(journal, first_tid, block_nr, freed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( tid_t, tail_sequence ) + __field( tid_t, first_tid ) + __field(unsigned long, block_nr ) + __field(unsigned long, freed ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->tail_sequence = journal->j_tail_sequence; + __entry->first_tid = first_tid; + __entry->block_nr = block_nr; + __entry->freed = freed; + ), + + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->tail_sequence, __entry->first_tid, + __entry->block_nr, __entry->freed) +); + +#endif /* _TRACE_JBD2_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/kmem.h b/instrumentation/events/mainline/kmem.h new file mode 100644 index 0000000..a9c87ad --- /dev/null +++ b/instrumentation/events/mainline/kmem.h @@ -0,0 +1,308 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM kmem + +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_KMEM_H + +#include +#include +#include "gfpflags.h" + +DECLARE_EVENT_CLASS(kmem_alloc, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags)) +); + +DEFINE_EVENT(kmem_alloc, kmalloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +); + +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) +); + +DECLARE_EVENT_CLASS(kmem_alloc_node, + + TP_PROTO(unsigned long call_site, + const void *ptr, + size_t bytes_req, + size_t bytes_alloc, + gfp_t gfp_flags, + int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + __field( size_t, bytes_req ) + __field( size_t, bytes_alloc ) + __field( gfp_t, gfp_flags ) + __field( int, node ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + __entry->bytes_req = bytes_req; + __entry->bytes_alloc = bytes_alloc; + __entry->gfp_flags = gfp_flags; + __entry->node = node; + ), + + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", + __entry->call_site, + __entry->ptr, + __entry->bytes_req, + __entry->bytes_alloc, + show_gfp_flags(__entry->gfp_flags), + __entry->node) +); + +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +); + +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, + + TP_PROTO(unsigned long call_site, const void *ptr, + size_t bytes_req, size_t bytes_alloc, + gfp_t gfp_flags, int node), + + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) +); + +DECLARE_EVENT_CLASS(kmem_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr), + + TP_STRUCT__entry( + __field( unsigned long, call_site ) + __field( const void *, ptr ) + ), + + TP_fast_assign( + __entry->call_site = call_site; + __entry->ptr = ptr; + ), + + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) +); + +DEFINE_EVENT(kmem_free, kfree, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +); + +DEFINE_EVENT(kmem_free, kmem_cache_free, + + TP_PROTO(unsigned long call_site, const void *ptr), + + TP_ARGS(call_site, ptr) +); + +TRACE_EVENT(mm_page_free_direct, + + TP_PROTO(struct page *page, unsigned int order), + + TP_ARGS(page, order), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->order = order; + ), + + TP_printk("page=%p pfn=%lu order=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order) +); + +TRACE_EVENT(mm_pagevec_free, + + TP_PROTO(struct page *page, int cold), + + TP_ARGS(page, cold), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, cold ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->cold = cold; + ), + + TP_printk("page=%p pfn=%lu order=0 cold=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->cold) +); + +TRACE_EVENT(mm_page_alloc, + + TP_PROTO(struct page *page, unsigned int order, + gfp_t gfp_flags, int migratetype), + + TP_ARGS(page, order, gfp_flags, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( gfp_t, gfp_flags ) + __field( int, migratetype ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->order = order; + __entry->gfp_flags = gfp_flags; + __entry->migratetype = migratetype; + ), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + show_gfp_flags(__entry->gfp_flags)) +); + +DECLARE_EVENT_CLASS(mm_page, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( unsigned int, order ) + __field( int, migratetype ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->order = order; + __entry->migratetype = migratetype; + ), + + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->order, + __entry->migratetype, + __entry->order == 0) +); + +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype) +); + +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, + + TP_PROTO(struct page *page, unsigned int order, int migratetype), + + TP_ARGS(page, order, migratetype), + + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", + __entry->page, page_to_pfn(__entry->page), + __entry->order, __entry->migratetype) +); + +TRACE_EVENT(mm_page_alloc_extfrag, + + TP_PROTO(struct page *page, + int alloc_order, int fallback_order, + int alloc_migratetype, int fallback_migratetype), + + TP_ARGS(page, + alloc_order, fallback_order, + alloc_migratetype, fallback_migratetype), + + TP_STRUCT__entry( + __field( struct page *, page ) + __field( int, alloc_order ) + __field( int, fallback_order ) + __field( int, alloc_migratetype ) + __field( int, fallback_migratetype ) + ), + + TP_fast_assign( + __entry->page = page; + __entry->alloc_order = alloc_order; + __entry->fallback_order = fallback_order; + __entry->alloc_migratetype = alloc_migratetype; + __entry->fallback_migratetype = fallback_migratetype; + ), + + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", + __entry->page, + page_to_pfn(__entry->page), + __entry->alloc_order, + __entry->fallback_order, + pageblock_order, + __entry->alloc_migratetype, + __entry->fallback_migratetype, + __entry->fallback_order < pageblock_order, + __entry->alloc_migratetype == __entry->fallback_migratetype) +); + +#endif /* _TRACE_KMEM_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/lock.h b/instrumentation/events/mainline/lock.h new file mode 100644 index 0000000..2821b86 --- /dev/null +++ b/instrumentation/events/mainline/lock.h @@ -0,0 +1,86 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lock + +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_LOCK_H + +#include +#include + +#ifdef CONFIG_LOCKDEP + +TRACE_EVENT(lock_acquire, + + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, + int trylock, int read, int check, + struct lockdep_map *next_lock, unsigned long ip), + + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), + + TP_STRUCT__entry( + __field(unsigned int, flags) + __string(name, lock->name) + __field(void *, lockdep_addr) + ), + + TP_fast_assign( + __entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0); + __assign_str(name, lock->name); + __entry->lockdep_addr = lock; + ), + + TP_printk("%p %s%s%s", __entry->lockdep_addr, + (__entry->flags & 1) ? "try " : "", + (__entry->flags & 2) ? "read " : "", + __get_str(name)) +); + +DECLARE_EVENT_CLASS(lock, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip), + + TP_STRUCT__entry( + __string( name, lock->name ) + __field( void *, lockdep_addr ) + ), + + TP_fast_assign( + __assign_str(name, lock->name); + __entry->lockdep_addr = lock; + ), + + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) +); + +DEFINE_EVENT(lock, lock_release, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +); + +#ifdef CONFIG_LOCK_STAT + +DEFINE_EVENT(lock, lock_contended, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +); + +DEFINE_EVENT(lock, lock_acquired, + + TP_PROTO(struct lockdep_map *lock, unsigned long ip), + + TP_ARGS(lock, ip) +); + +#endif +#endif + +#endif /* _TRACE_LOCK_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/module.h b/instrumentation/events/mainline/module.h new file mode 100644 index 0000000..21a546d --- /dev/null +++ b/instrumentation/events/mainline/module.h @@ -0,0 +1,131 @@ +/* + * Because linux/module.h has tracepoints in the header, and ftrace.h + * eventually includes this file, define_trace.h includes linux/module.h + * But we do not want the module.h to override the TRACE_SYSTEM macro + * variable that define_trace.h is processing, so we only set it + * when module events are being processed, which would happen when + * CREATE_TRACE_POINTS is defined. + */ +#ifdef CREATE_TRACE_POINTS +#undef TRACE_SYSTEM +#define TRACE_SYSTEM module +#endif + +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MODULE_H + +#include + +#ifdef CONFIG_MODULES + +struct module; + +#define show_module_flags(flags) __print_flags(flags, "", \ + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ + { (1UL << TAINT_FORCED_MODULE), "F" }, \ + { (1UL << TAINT_CRAP), "C" }) + +TRACE_EVENT(module_load, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __field( unsigned int, taints ) + __string( name, mod->name ) + ), + + TP_fast_assign( + __entry->taints = mod->taints; + __assign_str(name, mod->name); + ), + + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) +); + +TRACE_EVENT(module_free, + + TP_PROTO(struct module *mod), + + TP_ARGS(mod), + + TP_STRUCT__entry( + __string( name, mod->name ) + ), + + TP_fast_assign( + __assign_str(name, mod->name); + ), + + TP_printk("%s", __get_str(name)) +); + +#ifdef CONFIG_MODULE_UNLOAD +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ + +DECLARE_EVENT_CLASS(module_refcnt, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( int, refcnt ) + __string( name, mod->name ) + ), + + TP_fast_assign( + __entry->ip = ip; + __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs); + __assign_str(name, mod->name); + ), + + TP_printk("%s call_site=%pf refcnt=%d", + __get_str(name), (void *)__entry->ip, __entry->refcnt) +); + +DEFINE_EVENT(module_refcnt, module_get, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +); + +DEFINE_EVENT(module_refcnt, module_put, + + TP_PROTO(struct module *mod, unsigned long ip), + + TP_ARGS(mod, ip) +); +#endif /* CONFIG_MODULE_UNLOAD */ + +TRACE_EVENT(module_request, + + TP_PROTO(char *name, bool wait, unsigned long ip), + + TP_ARGS(name, wait, ip), + + TP_STRUCT__entry( + __field( unsigned long, ip ) + __field( bool, wait ) + __string( name, name ) + ), + + TP_fast_assign( + __entry->ip = ip; + __entry->wait = wait; + __assign_str(name, name); + ), + + TP_printk("%s wait=%d call_site=%pf", + __get_str(name), (int)__entry->wait, (void *)__entry->ip) +); + +#endif /* CONFIG_MODULES */ + +#endif /* _TRACE_MODULE_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/napi.h b/instrumentation/events/mainline/napi.h new file mode 100644 index 0000000..8fe1e93 --- /dev/null +++ b/instrumentation/events/mainline/napi.h @@ -0,0 +1,38 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM napi + +#if !defined(_TRACE_NAPI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NAPI_H_ + +#include +#include +#include + +#define NO_DEV "(no_device)" + +TRACE_EVENT(napi_poll, + + TP_PROTO(struct napi_struct *napi), + + TP_ARGS(napi), + + TP_STRUCT__entry( + __field( struct napi_struct *, napi) + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) + ), + + TP_fast_assign( + __entry->napi = napi; + __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV); + ), + + TP_printk("napi poll on napi struct %p for device %s", + __entry->napi, __get_str(dev_name)) +); + +#undef NO_DEV + +#endif /* _TRACE_NAPI_H_ */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/net.h b/instrumentation/events/mainline/net.h new file mode 100644 index 0000000..f99645d --- /dev/null +++ b/instrumentation/events/mainline/net.h @@ -0,0 +1,84 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM net + +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NET_H + +#include +#include +#include +#include + +TRACE_EVENT(net_dev_xmit, + + TP_PROTO(struct sk_buff *skb, + int rc, + struct net_device *dev, + unsigned int skb_len), + + TP_ARGS(skb, rc, dev, skb_len), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __field( int, rc ) + __string( name, dev->name ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->len = skb_len; + __entry->rc = rc; + __assign_str(name, dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) +); + +DECLARE_EVENT_CLASS(net_dev_template, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( unsigned int, len ) + __string( name, skb->dev->name ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->len = skb->len; + __assign_str(name, skb->dev->name); + ), + + TP_printk("dev=%s skbaddr=%p len=%u", + __get_str(name), __entry->skbaddr, __entry->len) +) + +DEFINE_EVENT(net_dev_template, net_dev_queue, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +); + +DEFINE_EVENT(net_dev_template, netif_receive_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +); + +DEFINE_EVENT(net_dev_template, netif_rx, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb) +); +#endif /* _TRACE_NET_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/power.h b/instrumentation/events/mainline/power.h new file mode 100644 index 0000000..1bcc2a8 --- /dev/null +++ b/instrumentation/events/mainline/power.h @@ -0,0 +1,240 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM power + +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_POWER_H + +#include +#include + +DECLARE_EVENT_CLASS(cpu, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id), + + TP_STRUCT__entry( + __field( u32, state ) + __field( u32, cpu_id ) + ), + + TP_fast_assign( + __entry->state = state; + __entry->cpu_id = cpu_id; + ), + + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, + (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(cpu, cpu_idle, + + TP_PROTO(unsigned int state, unsigned int cpu_id), + + TP_ARGS(state, cpu_id) +); + +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING + +#define PWR_EVENT_EXIT -1 +#endif + +DEFINE_EVENT(cpu, cpu_frequency, + + TP_PROTO(unsigned int frequency, unsigned int cpu_id), + + TP_ARGS(frequency, cpu_id) +); + +TRACE_EVENT(machine_suspend, + + TP_PROTO(unsigned int state), + + TP_ARGS(state), + + TP_STRUCT__entry( + __field( u32, state ) + ), + + TP_fast_assign( + __entry->state = state; + ), + + TP_printk("state=%lu", (unsigned long)__entry->state) +); + +/* This code will be removed after deprecation time exceeded (2.6.41) */ +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED + +/* + * The power events are used for cpuidle & suspend (power_start, power_end) + * and for cpufreq (power_frequency) + */ +DECLARE_EVENT_CLASS(power, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id), + + TP_STRUCT__entry( + __field( u64, type ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __entry->type = type; + __entry->state = state; + __entry->cpu_id = cpu_id; + ), + + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(power, power_start, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +); + +DEFINE_EVENT(power, power_frequency, + + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), + + TP_ARGS(type, state, cpu_id) +); + +TRACE_EVENT(power_end, + + TP_PROTO(unsigned int cpu_id), + + TP_ARGS(cpu_id), + + TP_STRUCT__entry( + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __entry->cpu_id = cpu_id; + ), + + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) + +); + +/* Deprecated dummy functions must be protected against multi-declartion */ +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED + +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED +enum { + POWER_NONE = 0, + POWER_CSTATE = 1, + POWER_PSTATE = 2, +}; + +/* These dummy declaration have to be ripped out when the deprecated + events get removed */ +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; +static inline void trace_power_end(u64 cpuid) {}; +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ + +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ + +/* + * The clock events are used for clock enable/disable and for + * clock rate change + */ +DECLARE_EVENT_CLASS(clock, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->state = state; + __entry->cpu_id = cpu_id; + ), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(clock, clock_enable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); + +DEFINE_EVENT(clock, clock_disable, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); + +DEFINE_EVENT(clock, clock_set_rate, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); + +/* + * The power domain events are used for power domains transitions + */ +DECLARE_EVENT_CLASS(power_domain, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + __field( u64, cpu_id ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->state = state; + __entry->cpu_id = cpu_id; +), + + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) +); + +DEFINE_EVENT(power_domain, power_domain_target, + + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), + + TP_ARGS(name, state, cpu_id) +); +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/regulator.h b/instrumentation/events/mainline/regulator.h new file mode 100644 index 0000000..37502a7 --- /dev/null +++ b/instrumentation/events/mainline/regulator.h @@ -0,0 +1,141 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM regulator + +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_REGULATOR_H + +#include +#include + +/* + * Events which just log themselves and the regulator name for enable/disable + * type tracking. + */ +DECLARE_EVENT_CLASS(regulator_basic, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + __assign_str(name, name); + ), + + TP_printk("name=%s", __get_str(name)) + +); + +DEFINE_EVENT(regulator_basic, regulator_enable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_enable_delay, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_enable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_disable, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +DEFINE_EVENT(regulator_basic, regulator_disable_complete, + + TP_PROTO(const char *name), + + TP_ARGS(name) + +); + +/* + * Events that take a range of numerical values, mostly for voltages + * and so on. + */ +DECLARE_EVENT_CLASS(regulator_range, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max), + + TP_STRUCT__entry( + __string( name, name ) + __field( int, min ) + __field( int, max ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->min = min; + __entry->max = max; + ), + + TP_printk("name=%s (%d-%d)", __get_str(name), + (int)__entry->min, (int)__entry->max) +); + +DEFINE_EVENT(regulator_range, regulator_set_voltage, + + TP_PROTO(const char *name, int min, int max), + + TP_ARGS(name, min, max) + +); + + +/* + * Events that take a single value, mostly for readback and refcounts. + */ +DECLARE_EVENT_CLASS(regulator_value, + + TP_PROTO(const char *name, unsigned int val), + + TP_ARGS(name, val), + + TP_STRUCT__entry( + __string( name, name ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->val = val; + ), + + TP_printk("name=%s, val=%u", __get_str(name), + (int)__entry->val) +); + +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, + + TP_PROTO(const char *name, unsigned int value), + + TP_ARGS(name, value) + +); + +#endif /* _TRACE_POWER_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/scsi.h b/instrumentation/events/mainline/scsi.h new file mode 100644 index 0000000..db6c935 --- /dev/null +++ b/instrumentation/events/mainline/scsi.h @@ -0,0 +1,365 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM scsi + +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SCSI_H + +#include +#include +#include +#include + +#define scsi_opcode_name(opcode) { opcode, #opcode } +#define show_opcode_name(val) \ + __print_symbolic(val, \ + scsi_opcode_name(TEST_UNIT_READY), \ + scsi_opcode_name(REZERO_UNIT), \ + scsi_opcode_name(REQUEST_SENSE), \ + scsi_opcode_name(FORMAT_UNIT), \ + scsi_opcode_name(READ_BLOCK_LIMITS), \ + scsi_opcode_name(REASSIGN_BLOCKS), \ + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ + scsi_opcode_name(READ_6), \ + scsi_opcode_name(WRITE_6), \ + scsi_opcode_name(SEEK_6), \ + scsi_opcode_name(READ_REVERSE), \ + scsi_opcode_name(WRITE_FILEMARKS), \ + scsi_opcode_name(SPACE), \ + scsi_opcode_name(INQUIRY), \ + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ + scsi_opcode_name(MODE_SELECT), \ + scsi_opcode_name(RESERVE), \ + scsi_opcode_name(RELEASE), \ + scsi_opcode_name(COPY), \ + scsi_opcode_name(ERASE), \ + scsi_opcode_name(MODE_SENSE), \ + scsi_opcode_name(START_STOP), \ + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ + scsi_opcode_name(SEND_DIAGNOSTIC), \ + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ + scsi_opcode_name(SET_WINDOW), \ + scsi_opcode_name(READ_CAPACITY), \ + scsi_opcode_name(READ_10), \ + scsi_opcode_name(WRITE_10), \ + scsi_opcode_name(SEEK_10), \ + scsi_opcode_name(POSITION_TO_ELEMENT), \ + scsi_opcode_name(WRITE_VERIFY), \ + scsi_opcode_name(VERIFY), \ + scsi_opcode_name(SEARCH_HIGH), \ + scsi_opcode_name(SEARCH_EQUAL), \ + scsi_opcode_name(SEARCH_LOW), \ + scsi_opcode_name(SET_LIMITS), \ + scsi_opcode_name(PRE_FETCH), \ + scsi_opcode_name(READ_POSITION), \ + scsi_opcode_name(SYNCHRONIZE_CACHE), \ + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ + scsi_opcode_name(READ_DEFECT_DATA), \ + scsi_opcode_name(MEDIUM_SCAN), \ + scsi_opcode_name(COMPARE), \ + scsi_opcode_name(COPY_VERIFY), \ + scsi_opcode_name(WRITE_BUFFER), \ + scsi_opcode_name(READ_BUFFER), \ + scsi_opcode_name(UPDATE_BLOCK), \ + scsi_opcode_name(READ_LONG), \ + scsi_opcode_name(WRITE_LONG), \ + scsi_opcode_name(CHANGE_DEFINITION), \ + scsi_opcode_name(WRITE_SAME), \ + scsi_opcode_name(UNMAP), \ + scsi_opcode_name(READ_TOC), \ + scsi_opcode_name(LOG_SELECT), \ + scsi_opcode_name(LOG_SENSE), \ + scsi_opcode_name(XDWRITEREAD_10), \ + scsi_opcode_name(MODE_SELECT_10), \ + scsi_opcode_name(RESERVE_10), \ + scsi_opcode_name(RELEASE_10), \ + scsi_opcode_name(MODE_SENSE_10), \ + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ + scsi_opcode_name(REPORT_LUNS), \ + scsi_opcode_name(MAINTENANCE_IN), \ + scsi_opcode_name(MAINTENANCE_OUT), \ + scsi_opcode_name(MOVE_MEDIUM), \ + scsi_opcode_name(EXCHANGE_MEDIUM), \ + scsi_opcode_name(READ_12), \ + scsi_opcode_name(WRITE_12), \ + scsi_opcode_name(WRITE_VERIFY_12), \ + scsi_opcode_name(SEARCH_HIGH_12), \ + scsi_opcode_name(SEARCH_EQUAL_12), \ + scsi_opcode_name(SEARCH_LOW_12), \ + scsi_opcode_name(READ_ELEMENT_STATUS), \ + scsi_opcode_name(SEND_VOLUME_TAG), \ + scsi_opcode_name(WRITE_LONG_2), \ + scsi_opcode_name(READ_16), \ + scsi_opcode_name(WRITE_16), \ + scsi_opcode_name(VERIFY_16), \ + scsi_opcode_name(WRITE_SAME_16), \ + scsi_opcode_name(SERVICE_ACTION_IN), \ + scsi_opcode_name(SAI_READ_CAPACITY_16), \ + scsi_opcode_name(SAI_GET_LBA_STATUS), \ + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ + scsi_opcode_name(MO_SET_TARGET_PGS), \ + scsi_opcode_name(READ_32), \ + scsi_opcode_name(WRITE_32), \ + scsi_opcode_name(WRITE_SAME_32), \ + scsi_opcode_name(ATA_16), \ + scsi_opcode_name(ATA_12)) + +#define scsi_hostbyte_name(result) { result, #result } +#define show_hostbyte_name(val) \ + __print_symbolic(val, \ + scsi_hostbyte_name(DID_OK), \ + scsi_hostbyte_name(DID_NO_CONNECT), \ + scsi_hostbyte_name(DID_BUS_BUSY), \ + scsi_hostbyte_name(DID_TIME_OUT), \ + scsi_hostbyte_name(DID_BAD_TARGET), \ + scsi_hostbyte_name(DID_ABORT), \ + scsi_hostbyte_name(DID_PARITY), \ + scsi_hostbyte_name(DID_ERROR), \ + scsi_hostbyte_name(DID_RESET), \ + scsi_hostbyte_name(DID_BAD_INTR), \ + scsi_hostbyte_name(DID_PASSTHROUGH), \ + scsi_hostbyte_name(DID_SOFT_ERROR), \ + scsi_hostbyte_name(DID_IMM_RETRY), \ + scsi_hostbyte_name(DID_REQUEUE), \ + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) + +#define scsi_driverbyte_name(result) { result, #result } +#define show_driverbyte_name(val) \ + __print_symbolic(val, \ + scsi_driverbyte_name(DRIVER_OK), \ + scsi_driverbyte_name(DRIVER_BUSY), \ + scsi_driverbyte_name(DRIVER_SOFT), \ + scsi_driverbyte_name(DRIVER_MEDIA), \ + scsi_driverbyte_name(DRIVER_ERROR), \ + scsi_driverbyte_name(DRIVER_INVALID), \ + scsi_driverbyte_name(DRIVER_TIMEOUT), \ + scsi_driverbyte_name(DRIVER_HARD), \ + scsi_driverbyte_name(DRIVER_SENSE)) + +#define scsi_msgbyte_name(result) { result, #result } +#define show_msgbyte_name(val) \ + __print_symbolic(val, \ + scsi_msgbyte_name(COMMAND_COMPLETE), \ + scsi_msgbyte_name(EXTENDED_MESSAGE), \ + scsi_msgbyte_name(SAVE_POINTERS), \ + scsi_msgbyte_name(RESTORE_POINTERS), \ + scsi_msgbyte_name(DISCONNECT), \ + scsi_msgbyte_name(INITIATOR_ERROR), \ + scsi_msgbyte_name(ABORT_TASK_SET), \ + scsi_msgbyte_name(MESSAGE_REJECT), \ + scsi_msgbyte_name(NOP), \ + scsi_msgbyte_name(MSG_PARITY_ERROR), \ + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ + scsi_msgbyte_name(TARGET_RESET), \ + scsi_msgbyte_name(ABORT_TASK), \ + scsi_msgbyte_name(CLEAR_TASK_SET), \ + scsi_msgbyte_name(INITIATE_RECOVERY), \ + scsi_msgbyte_name(RELEASE_RECOVERY), \ + scsi_msgbyte_name(CLEAR_ACA), \ + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ + scsi_msgbyte_name(ACA), \ + scsi_msgbyte_name(QAS_REQUEST), \ + scsi_msgbyte_name(BUS_DEVICE_RESET), \ + scsi_msgbyte_name(ABORT)) + +#define scsi_statusbyte_name(result) { result, #result } +#define show_statusbyte_name(val) \ + __print_symbolic(val, \ + scsi_statusbyte_name(SAM_STAT_GOOD), \ + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_BUSY), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) + +#define scsi_prot_op_name(result) { result, #result } +#define show_prot_op_name(val) \ + __print_symbolic(val, \ + scsi_prot_op_name(SCSI_PROT_NORMAL), \ + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) + +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) + +TRACE_EVENT(scsi_dispatch_cmd_start, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + __entry->host_no = cmd->device->host->host_no; + __entry->channel = cmd->device->channel; + __entry->id = cmd->device->id; + __entry->lun = cmd->device->lun; + __entry->opcode = cmd->cmnd[0]; + __entry->cmd_len = cmd->cmd_len; + __entry->data_sglen = scsi_sg_count(cmd); + __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) +); + +TRACE_EVENT(scsi_dispatch_cmd_error, + + TP_PROTO(struct scsi_cmnd *cmd, int rtn), + + TP_ARGS(cmd, rtn), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, rtn ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + __entry->host_no = cmd->device->host->host_no; + __entry->channel = cmd->device->channel; + __entry->id = cmd->device->id; + __entry->lun = cmd->device->lun; + __entry->rtn = rtn; + __entry->opcode = cmd->cmnd[0]; + __entry->cmd_len = cmd->cmd_len; + __entry->data_sglen = scsi_sg_count(cmd); + __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + __entry->rtn) +); + +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, + + TP_PROTO(struct scsi_cmnd *cmd), + + TP_ARGS(cmd), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + __field( unsigned int, channel ) + __field( unsigned int, id ) + __field( unsigned int, lun ) + __field( int, result ) + __field( unsigned int, opcode ) + __field( unsigned int, cmd_len ) + __field( unsigned int, data_sglen ) + __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) + ), + + TP_fast_assign( + __entry->host_no = cmd->device->host->host_no; + __entry->channel = cmd->device->channel; + __entry->id = cmd->device->id; + __entry->lun = cmd->device->lun; + __entry->result = cmd->result; + __entry->opcode = cmd->cmnd[0]; + __entry->cmd_len = cmd->cmd_len; + __entry->data_sglen = scsi_sg_count(cmd); + __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); + ), + + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ + "%s host=%s message=%s status=%s)", + __entry->host_no, __entry->channel, __entry->id, + __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), + show_opcode_name(__entry->opcode), + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), + show_driverbyte_name(((__entry->result) >> 24) & 0xff), + show_hostbyte_name(((__entry->result) >> 16) & 0xff), + show_msgbyte_name(((__entry->result) >> 8) & 0xff), + show_statusbyte_name(__entry->result & 0xff)) +); + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)); + +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, + TP_PROTO(struct scsi_cmnd *cmd), + TP_ARGS(cmd)); + +TRACE_EVENT(scsi_eh_wakeup, + + TP_PROTO(struct Scsi_Host *shost), + + TP_ARGS(shost), + + TP_STRUCT__entry( + __field( unsigned int, host_no ) + ), + + TP_fast_assign( + __entry->host_no = shost->host_no; + ), + + TP_printk("host_no=%u", __entry->host_no) +); + +#endif /* _TRACE_SCSI_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/skb.h b/instrumentation/events/mainline/skb.h new file mode 100644 index 0000000..0c68ae2 --- /dev/null +++ b/instrumentation/events/mainline/skb.h @@ -0,0 +1,75 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM skb + +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SKB_H + +#include +#include +#include + +/* + * Tracepoint for free an sk_buff: + */ +TRACE_EVENT(kfree_skb, + + TP_PROTO(struct sk_buff *skb, void *location), + + TP_ARGS(skb, location), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + __field( void *, location ) + __field( unsigned short, protocol ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->location = location; + __entry->protocol = ntohs(skb->protocol); + ), + + TP_printk("skbaddr=%p protocol=%u location=%p", + __entry->skbaddr, __entry->protocol, __entry->location) +); + +TRACE_EVENT(consume_skb, + + TP_PROTO(struct sk_buff *skb), + + TP_ARGS(skb), + + TP_STRUCT__entry( + __field( void *, skbaddr ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + ), + + TP_printk("skbaddr=%p", __entry->skbaddr) +); + +TRACE_EVENT(skb_copy_datagram_iovec, + + TP_PROTO(const struct sk_buff *skb, int len), + + TP_ARGS(skb, len), + + TP_STRUCT__entry( + __field( const void *, skbaddr ) + __field( int, len ) + ), + + TP_fast_assign( + __entry->skbaddr = skb; + __entry->len = len; + ), + + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) +); + +#endif /* _TRACE_SKB_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/sock.h b/instrumentation/events/mainline/sock.h new file mode 100644 index 0000000..779abb9 --- /dev/null +++ b/instrumentation/events/mainline/sock.h @@ -0,0 +1,68 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sock + +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SOCK_H + +#include +#include + +TRACE_EVENT(sock_rcvqueue_full, + + TP_PROTO(struct sock *sk, struct sk_buff *skb), + + TP_ARGS(sk, skb), + + TP_STRUCT__entry( + __field(int, rmem_alloc) + __field(unsigned int, truesize) + __field(int, sk_rcvbuf) + ), + + TP_fast_assign( + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); + __entry->truesize = skb->truesize; + __entry->sk_rcvbuf = sk->sk_rcvbuf; + ), + + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) +); + +TRACE_EVENT(sock_exceed_buf_limit, + + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), + + TP_ARGS(sk, prot, allocated), + + TP_STRUCT__entry( + __array(char, name, 32) + __field(long *, sysctl_mem) + __field(long, allocated) + __field(int, sysctl_rmem) + __field(int, rmem_alloc) + ), + + TP_fast_assign( + strncpy(__entry->name, prot->name, 32); + __entry->sysctl_mem = prot->sysctl_mem; + __entry->allocated = allocated; + __entry->sysctl_rmem = prot->sysctl_rmem[0]; + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); + ), + + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " + "sysctl_rmem=%d rmem_alloc=%d", + __entry->name, + __entry->sysctl_mem[0], + __entry->sysctl_mem[1], + __entry->sysctl_mem[2], + __entry->allocated, + __entry->sysctl_rmem, + __entry->rmem_alloc) +); + +#endif /* _TRACE_SOCK_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/udp.h b/instrumentation/events/mainline/udp.h new file mode 100644 index 0000000..a664bb9 --- /dev/null +++ b/instrumentation/events/mainline/udp.h @@ -0,0 +1,32 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM udp + +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_UDP_H + +#include +#include + +TRACE_EVENT(udp_fail_queue_rcv_skb, + + TP_PROTO(int rc, struct sock *sk), + + TP_ARGS(rc, sk), + + TP_STRUCT__entry( + __field(int, rc) + __field(__u16, lport) + ), + + TP_fast_assign( + __entry->rc = rc; + __entry->lport = inet_sk(sk)->inet_num; + ), + + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) +); + +#endif /* _TRACE_UDP_H */ + +/* This part must be outside protection */ +#include diff --git a/instrumentation/events/mainline/vmscan.h b/instrumentation/events/mainline/vmscan.h new file mode 100644 index 0000000..36851f7 --- /dev/null +++ b/instrumentation/events/mainline/vmscan.h @@ -0,0 +1,477 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM vmscan + +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_VMSCAN_H + +#include +#include +#include +#include +#include "gfpflags.h" + +#define RECLAIM_WB_ANON 0x0001u +#define RECLAIM_WB_FILE 0x0002u +#define RECLAIM_WB_MIXED 0x0010u +#define RECLAIM_WB_SYNC 0x0004u +#define RECLAIM_WB_ASYNC 0x0008u + +#define show_reclaim_flags(flags) \ + (flags) ? __print_flags(flags, "|", \ + {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ + {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ + {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ + {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ + {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ + ) : "RECLAIM_WB_NONE" + +#define trace_reclaim_flags(page, sync) ( \ + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + ) + +#define trace_shrink_flags(file, sync) ( \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + ) + +TRACE_EVENT(mm_vmscan_kswapd_sleep, + + TP_PROTO(int nid), + + TP_ARGS(nid), + + TP_STRUCT__entry( + __field( int, nid ) + ), + + TP_fast_assign( + __entry->nid = nid; + ), + + TP_printk("nid=%d", __entry->nid) +); + +TRACE_EVENT(mm_vmscan_kswapd_wake, + + TP_PROTO(int nid, int order), + + TP_ARGS(nid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, order ) + ), + + TP_fast_assign( + __entry->nid = nid; + __entry->order = order; + ), + + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) +); + +TRACE_EVENT(mm_vmscan_wakeup_kswapd, + + TP_PROTO(int nid, int zid, int order), + + TP_ARGS(nid, zid, order), + + TP_STRUCT__entry( + __field( int, nid ) + __field( int, zid ) + __field( int, order ) + ), + + TP_fast_assign( + __entry->nid = nid; + __entry->zid = zid; + __entry->order = order; + ), + + TP_printk("nid=%d zid=%d order=%d", + __entry->nid, + __entry->zid, + __entry->order) +); + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags), + + TP_STRUCT__entry( + __field( int, order ) + __field( int, may_writepage ) + __field( gfp_t, gfp_flags ) + ), + + TP_fast_assign( + __entry->order = order; + __entry->may_writepage = may_writepage; + __entry->gfp_flags = gfp_flags; + ), + + TP_printk("order=%d may_writepage=%d gfp_flags=%s", + __entry->order, + __entry->may_writepage, + show_gfp_flags(__entry->gfp_flags)) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, + + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), + + TP_ARGS(order, may_writepage, gfp_flags) +); + +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed), + + TP_STRUCT__entry( + __field( unsigned long, nr_reclaimed ) + ), + + TP_fast_assign( + __entry->nr_reclaimed = nr_reclaimed; + ), + + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +); + +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, + + TP_PROTO(unsigned long nr_reclaimed), + + TP_ARGS(nr_reclaimed) +); + +TRACE_EVENT(mm_shrink_slab_start, + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, + long nr_objects_to_shrink, unsigned long pgs_scanned, + unsigned long lru_pgs, unsigned long cache_items, + unsigned long long delta, unsigned long total_scan), + + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, + cache_items, delta, total_scan), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, nr_objects_to_shrink) + __field(gfp_t, gfp_flags) + __field(unsigned long, pgs_scanned) + __field(unsigned long, lru_pgs) + __field(unsigned long, cache_items) + __field(unsigned long long, delta) + __field(unsigned long, total_scan) + ), + + TP_fast_assign( + __entry->shr = shr; + __entry->shrink = shr->shrink; + __entry->nr_objects_to_shrink = nr_objects_to_shrink; + __entry->gfp_flags = sc->gfp_mask; + __entry->pgs_scanned = pgs_scanned; + __entry->lru_pgs = lru_pgs; + __entry->cache_items = cache_items; + __entry->delta = delta; + __entry->total_scan = total_scan; + ), + + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", + __entry->shrink, + __entry->shr, + __entry->nr_objects_to_shrink, + show_gfp_flags(__entry->gfp_flags), + __entry->pgs_scanned, + __entry->lru_pgs, + __entry->cache_items, + __entry->delta, + __entry->total_scan) +); + +TRACE_EVENT(mm_shrink_slab_end, + TP_PROTO(struct shrinker *shr, int shrinker_retval, + long unused_scan_cnt, long new_scan_cnt), + + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), + + TP_STRUCT__entry( + __field(struct shrinker *, shr) + __field(void *, shrink) + __field(long, unused_scan) + __field(long, new_scan) + __field(int, retval) + __field(long, total_scan) + ), + + TP_fast_assign( + __entry->shr = shr; + __entry->shrink = shr->shrink; + __entry->unused_scan = unused_scan_cnt; + __entry->new_scan = new_scan_cnt; + __entry->retval = shrinker_retval; + __entry->total_scan = new_scan_cnt - unused_scan_cnt; + ), + + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", + __entry->shrink, + __entry->shr, + __entry->unused_scan, + __entry->new_scan, + __entry->total_scan, + __entry->retval) +); + +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, + int isolate_mode), + + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), + + TP_STRUCT__entry( + __field(int, order) + __field(unsigned long, nr_requested) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_taken) + __field(unsigned long, nr_lumpy_taken) + __field(unsigned long, nr_lumpy_dirty) + __field(unsigned long, nr_lumpy_failed) + __field(int, isolate_mode) + ), + + TP_fast_assign( + __entry->order = order; + __entry->nr_requested = nr_requested; + __entry->nr_scanned = nr_scanned; + __entry->nr_taken = nr_taken; + __entry->nr_lumpy_taken = nr_lumpy_taken; + __entry->nr_lumpy_dirty = nr_lumpy_dirty; + __entry->nr_lumpy_failed = nr_lumpy_failed; + __entry->isolate_mode = isolate_mode; + ), + + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", + __entry->isolate_mode, + __entry->order, + __entry->nr_requested, + __entry->nr_scanned, + __entry->nr_taken, + __entry->nr_lumpy_taken, + __entry->nr_lumpy_dirty, + __entry->nr_lumpy_failed) +); + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, + int isolate_mode), + + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) + +); + +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, + + TP_PROTO(int order, + unsigned long nr_requested, + unsigned long nr_scanned, + unsigned long nr_taken, + unsigned long nr_lumpy_taken, + unsigned long nr_lumpy_dirty, + unsigned long nr_lumpy_failed, + int isolate_mode), + + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) + +); + +TRACE_EVENT(mm_vmscan_writepage, + + TP_PROTO(struct page *page, + int reclaim_flags), + + TP_ARGS(page, reclaim_flags), + + TP_STRUCT__entry( + __field(struct page *, page) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + __entry->page = page; + __entry->reclaim_flags = reclaim_flags; + ), + + TP_printk("page=%p pfn=%lu flags=%s", + __entry->page, + page_to_pfn(__entry->page), + show_reclaim_flags(__entry->reclaim_flags)) +); + +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, + + TP_PROTO(int nid, int zid, + unsigned long nr_scanned, unsigned long nr_reclaimed, + int priority, int reclaim_flags), + + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), + + TP_STRUCT__entry( + __field(int, nid) + __field(int, zid) + __field(unsigned long, nr_scanned) + __field(unsigned long, nr_reclaimed) + __field(int, priority) + __field(int, reclaim_flags) + ), + + TP_fast_assign( + __entry->nid = nid; + __entry->zid = zid; + __entry->nr_scanned = nr_scanned; + __entry->nr_reclaimed = nr_reclaimed; + __entry->priority = priority; + __entry->reclaim_flags = reclaim_flags; + ), + + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", + __entry->nid, __entry->zid, + __entry->nr_scanned, __entry->nr_reclaimed, + __entry->priority, + show_reclaim_flags(__entry->reclaim_flags)) +); + +TRACE_EVENT(replace_swap_token, + TP_PROTO(struct mm_struct *old_mm, + struct mm_struct *new_mm), + + TP_ARGS(old_mm, new_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, old_mm) + __field(unsigned int, old_prio) + __field(struct mm_struct*, new_mm) + __field(unsigned int, new_prio) + ), + + TP_fast_assign( + __entry->old_mm = old_mm; + __entry->old_prio = old_mm ? old_mm->token_priority : 0; + __entry->new_mm = new_mm; + __entry->new_prio = new_mm->token_priority; + ), + + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", + __entry->old_mm, __entry->old_prio, + __entry->new_mm, __entry->new_prio) +); + +DECLARE_EVENT_CLASS(put_swap_token_template, + TP_PROTO(struct mm_struct *swap_token_mm), + + TP_ARGS(swap_token_mm), + + TP_STRUCT__entry( + __field(struct mm_struct*, swap_token_mm) + ), + + TP_fast_assign( + __entry->swap_token_mm = swap_token_mm; + ), + + TP_printk("token_mm=%p", __entry->swap_token_mm) +); + +DEFINE_EVENT(put_swap_token_template, put_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm) +); + +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, + TP_PROTO(struct mm_struct *swap_token_mm), + TP_ARGS(swap_token_mm), + TP_CONDITION(swap_token_mm != NULL) +); + +TRACE_EVENT_CONDITION(update_swap_token_priority, + TP_PROTO(struct mm_struct *mm, + unsigned int old_prio, + struct mm_struct *swap_token_mm), + + TP_ARGS(mm, old_prio, swap_token_mm), + + TP_CONDITION(mm->token_priority != old_prio), + + TP_STRUCT__entry( + __field(struct mm_struct*, mm) + __field(unsigned int, old_prio) + __field(unsigned int, new_prio) + __field(struct mm_struct*, swap_token_mm) + __field(unsigned int, swap_token_prio) + ), + + TP_fast_assign( + __entry->mm = mm; + __entry->old_prio = old_prio; + __entry->new_prio = mm->token_priority; + __entry->swap_token_mm = swap_token_mm; + __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0; + ), + + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", + __entry->mm, __entry->old_prio, __entry->new_prio, + __entry->swap_token_mm, __entry->swap_token_prio) +); + +#endif /* _TRACE_VMSCAN_H */ + +/* This part must be outside protection */ +#include diff --git a/probes/Makefile b/probes/Makefile index 6efd6ad..c39a84a 100644 --- a/probes/Makefile +++ b/probes/Makefile @@ -12,6 +12,9 @@ obj-m += lttng-probe-lttng.o obj-m += lttng-probe-sched.o obj-m += lttng-probe-irq.o obj-m += lttng-probe-timer.o +obj-m += lttng-probe-kmem.o +obj-m += lttng-probe-module.o +obj-m += lttng-probe-power.o obj-m += lttng-probe-statedump.o @@ -33,6 +36,75 @@ obj-m += $(shell \ endif endif +ifneq ($(CONFIG_NET),) +obj-m += lttng-probe-net.o +obj-m += lttng-probe-napi.o +obj-m += lttng-probe-skb.o +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-sock.o" ; fi;) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-udp.o" ; fi;) +endif + +ifneq ($(CONFIG_SND_SOC),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ + echo "lttng-probe-asoc.o" ; fi;) +endif + +ifneq ($(CONFIG_EXT3_FS),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-ext3.o" ; fi;) +endif + +ifneq ($(CONFIG_GPIOLIB),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 ] ; then \ + echo "lttng-probe-gpio.o" ; fi;) +endif + +ifneq ($(CONFIG_JBD2),) +obj-m += lttng-probe-jbd2.o +endif + +ifneq ($(CONFIG_JBD),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ + echo "lttng-probe-jbd.o" ; fi;) +endif + +ifneq ($(CONFIG_REGULATOR),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ + echo "lttng-probe-regulator.o" ; fi;) +endif + +ifneq ($(CONFIG_SCSI),) +obj-m += $(shell \ + if [ $(VERSION) -ge 3 ] ; then \ + echo "lttng-probe-scsi.o" ; fi;) +endif + +vmscan = $(shell \ + if [ $(VERSION) -ge 3 ] ; then \ + echo "lttng-probe-vmscan.o" ; fi;) +ifneq ($(CONFIG_SWAP),) + obj-m += $(vmscan) +else +ifneq ($(CONFIG_CGROUP_MEM_RES_CTLR),) + obj-m += $(vmscan) +endif +endif + +ifneq ($(CONFIG_LOCKDEP),) +obj-m += lttng-probe-lock.o +endif + ifneq ($(CONFIG_KPROBES),) obj-m += lttng-kprobes.o endif diff --git a/probes/lttng-probe-asoc.c b/probes/lttng-probe-asoc.c new file mode 100644 index 0000000..427639f --- /dev/null +++ b/probes/lttng-probe-asoc.c @@ -0,0 +1,45 @@ +/* + * probes/lttng-probe-block.c + * + * LTTng asoc probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/asoc.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng asoc probes"); diff --git a/probes/lttng-probe-ext3.c b/probes/lttng-probe-ext3.c new file mode 100644 index 0000000..0df2b67 --- /dev/null +++ b/probes/lttng-probe-ext3.c @@ -0,0 +1,56 @@ +/* + * probes/lttng-probe-ext3.c + * + * LTTng ext3 probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +/* + * Since 3.4 the is no linux/ext3_fs_i.h anymore. Instead we have to use + * ext3.h from fs/ext3/ext3.h (which also includes trace/events/ext3.h) + */ +#include "../instrumentation/events/mainline/fs_ext3.h" +#else +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include +#endif + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/ext3.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng ext3 probes"); diff --git a/probes/lttng-probe-gpio.c b/probes/lttng-probe-gpio.c new file mode 100644 index 0000000..51692a7 --- /dev/null +++ b/probes/lttng-probe-gpio.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-gpio.c + * + * LTTng gpio probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/gpio.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng gpio probes"); diff --git a/probes/lttng-probe-jbd.c b/probes/lttng-probe-jbd.c new file mode 100644 index 0000000..46911cc --- /dev/null +++ b/probes/lttng-probe-jbd.c @@ -0,0 +1,44 @@ +/* + * probes/lttng-probe-jbd.c + * + * LTTng jbd probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/jbd.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng jbd probes"); diff --git a/probes/lttng-probe-jbd2.c b/probes/lttng-probe-jbd2.c new file mode 100644 index 0000000..eea0a66 --- /dev/null +++ b/probes/lttng-probe-jbd2.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-jbd2.c + * + * LTTng jbd2 probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/jbd2.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng jbd2 probes"); diff --git a/probes/lttng-probe-kmem.c b/probes/lttng-probe-kmem.c new file mode 100644 index 0000000..af67759 --- /dev/null +++ b/probes/lttng-probe-kmem.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-kmem.c + * + * LTTng kmem probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/kmem.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng kmem probes"); diff --git a/probes/lttng-probe-lock.c b/probes/lttng-probe-lock.c new file mode 100644 index 0000000..16ac0e7 --- /dev/null +++ b/probes/lttng-probe-lock.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-lock.c + * + * LTTng lock probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/lock.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng lock probes"); diff --git a/probes/lttng-probe-module.c b/probes/lttng-probe-module.c new file mode 100644 index 0000000..1a3c255 --- /dev/null +++ b/probes/lttng-probe-module.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-module.c + * + * LTTng module probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/module.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng module probes"); diff --git a/probes/lttng-probe-napi.c b/probes/lttng-probe-napi.c new file mode 100644 index 0000000..cae8504 --- /dev/null +++ b/probes/lttng-probe-napi.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-napi.c + * + * LTTng napi probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/napi.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng napi probes"); diff --git a/probes/lttng-probe-net.c b/probes/lttng-probe-net.c new file mode 100644 index 0000000..54212be --- /dev/null +++ b/probes/lttng-probe-net.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-net.c + * + * LTTng net probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/net.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng net probes"); diff --git a/probes/lttng-probe-power.c b/probes/lttng-probe-power.c new file mode 100644 index 0000000..5dcb93f --- /dev/null +++ b/probes/lttng-probe-power.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-power.c + * + * LTTng power probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/power.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng power probes"); diff --git a/probes/lttng-probe-regulator.c b/probes/lttng-probe-regulator.c new file mode 100644 index 0000000..7c8b7f9 --- /dev/null +++ b/probes/lttng-probe-regulator.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-regulator.c + * + * LTTng regulator probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/regulator.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng regulator probes"); diff --git a/probes/lttng-probe-scsi.c b/probes/lttng-probe-scsi.c new file mode 100644 index 0000000..51702c3 --- /dev/null +++ b/probes/lttng-probe-scsi.c @@ -0,0 +1,44 @@ +/* + * probes/lttng-probe-scsi.c + * + * LTTng scsi probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/scsi.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng scsi probes"); diff --git a/probes/lttng-probe-skb.c b/probes/lttng-probe-skb.c new file mode 100644 index 0000000..52edf88 --- /dev/null +++ b/probes/lttng-probe-skb.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-skb.c + * + * LTTng skb probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/skb.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng skb probes"); diff --git a/probes/lttng-probe-sock.c b/probes/lttng-probe-sock.c new file mode 100644 index 0000000..b3e699a --- /dev/null +++ b/probes/lttng-probe-sock.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-sock.c + * + * LTTng sock probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/sock.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng sock probes"); diff --git a/probes/lttng-probe-udp.c b/probes/lttng-probe-udp.c new file mode 100644 index 0000000..51ec3cb --- /dev/null +++ b/probes/lttng-probe-udp.c @@ -0,0 +1,43 @@ +/* + * probes/lttng-probe-udp.c + * + * LTTng udp probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#include "../instrumentation/events/lttng-module/udp.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth "); +MODULE_DESCRIPTION("LTTng udp probes"); diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c new file mode 100644 index 0000000..2abd0e4 --- /dev/null +++ b/probes/lttng-probe-vmscan.c @@ -0,0 +1,48 @@ +/* + * probes/lttng-probe-vmscan.c + * + * LTTng vmscan probes. + * + * Copyright (C) 2010-2012 Mathieu Desnoyers + * Copyright (C) 2012 Mentor Graphics Corp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +/* + * Create the tracepoint static inlines from the kernel to validate that our + * trace event macros match the kernel we run on. + */ +#include + +/* + * Create LTTng tracepoint probes. + */ +#define LTTNG_PACKAGE_BUILD +#define CREATE_TRACE_POINTS +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) +typedef int isolate_mode_t; +#endif + +#include "../instrumentation/events/lttng-module/vmscan.h" + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); +MODULE_DESCRIPTION("LTTng vmscan probes"); -- 1.7.10.4 >From 5b1d2fa2044ba95020a12671da188fbe85967c80 Mon Sep 17 00:00:00 2001 From: Paul Woegerer Date: Tue, 13 Nov 2012 16:58:22 +0100 Subject: [PATCH 2/3] Add ifdefs to net probe to support Linux 2.6.39 --- instrumentation/events/lttng-module/net.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h index c25b0d9..589011c 100644 --- a/instrumentation/events/lttng-module/net.h +++ b/instrumentation/events/lttng-module/net.h @@ -8,29 +8,50 @@ #include #include #include +#include TRACE_EVENT(net_dev_xmit, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) TP_PROTO(struct sk_buff *skb, int rc, struct net_device *dev, unsigned int skb_len), TP_ARGS(skb, rc, dev, skb_len), +#else + TP_PROTO(struct sk_buff *skb, + int rc), + + TP_ARGS(skb, rc), +#endif TP_STRUCT__entry( __field( void *, skbaddr ) __field( unsigned int, len ) __field( int, rc ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) __string( name, dev->name ) +#else + __string( name, skb->dev->name ) +#endif ), +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) TP_fast_assign( tp_assign(skbaddr, skb); tp_assign(len, skb_len); tp_assign(rc, rc); tp_strcpy(name, dev->name); ), +#else + TP_fast_assign( + tp_assign(skbaddr, skb); + tp_assign(len, skb->len); + tp_assign(rc, rc); + tp_strcpy(name, skb->dev->name); + ), +#endif TP_printk("dev=%s skbaddr=%p len=%u rc=%d", __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) -- 1.7.10.4 >From 0f2be20124423c54865f9e45f035c75b8e7a5598 Mon Sep 17 00:00:00 2001 From: Paul Woegerer Date: Wed, 14 Nov 2012 10:10:49 +0100 Subject: [PATCH 3/3] Remove semicolons in TP_fast_assign blocks. --- instrumentation/events/lttng-module/asoc.h | 54 ++--- instrumentation/events/lttng-module/ext3.h | 238 +++++++++++------------ instrumentation/events/lttng-module/gpio.h | 12 +- instrumentation/events/lttng-module/jbd.h | 44 ++--- instrumentation/events/lttng-module/jbd2.h | 42 ++-- instrumentation/events/lttng-module/kmem.h | 58 +++--- instrumentation/events/lttng-module/lock.h | 10 +- instrumentation/events/lttng-module/module.h | 18 +- instrumentation/events/lttng-module/napi.h | 4 +- instrumentation/events/lttng-module/net.h | 22 +-- instrumentation/events/lttng-module/power.h | 26 +-- instrumentation/events/lttng-module/regulator.h | 12 +- instrumentation/events/lttng-module/scsi.h | 66 +++---- instrumentation/events/lttng-module/skb.h | 12 +- instrumentation/events/lttng-module/sock.h | 14 +- instrumentation/events/lttng-module/udp.h | 4 +- instrumentation/events/lttng-module/vmscan.h | 104 +++++----- 17 files changed, 370 insertions(+), 370 deletions(-) diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h index cb9e701..6ffc923 100644 --- a/instrumentation/events/lttng-module/asoc.h +++ b/instrumentation/events/lttng-module/asoc.h @@ -37,10 +37,10 @@ DECLARE_EVENT_CLASS(snd_soc_reg, ), TP_fast_assign( - tp_strcpy(name, codec->name); - tp_assign(id, codec->id); - tp_assign(reg, reg); - tp_assign(val, val); + tp_strcpy(name, codec->name) + tp_assign(id, codec->id) + tp_assign(reg, reg) + tp_assign(val, val) ), TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), @@ -82,10 +82,10 @@ DECLARE_EVENT_CLASS(snd_soc_preg, ), TP_fast_assign( - tp_strcpy(name, platform->name); - tp_assign(id, platform->id); - tp_assign(reg, reg); - tp_assign(val, val); + tp_strcpy(name, platform->name) + tp_assign(id, platform->id) + tp_assign(reg, reg) + tp_assign(val, val) ), TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), @@ -124,8 +124,8 @@ DECLARE_EVENT_CLASS(snd_soc_card, ), TP_fast_assign( - tp_strcpy(name, card->name); - tp_assign(val, val); + tp_strcpy(name, card->name) + tp_assign(val, val) ), TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) @@ -158,7 +158,7 @@ DECLARE_EVENT_CLASS(snd_soc_dapm_basic, ), TP_fast_assign( - tp_strcpy(name, card->name); + tp_strcpy(name, card->name) ), TP_printk("card=%s", __get_str(name)) @@ -192,8 +192,8 @@ DECLARE_EVENT_CLASS(snd_soc_dapm_widget, ), TP_fast_assign( - tp_strcpy(name, w->name); - tp_assign(val, val); + tp_strcpy(name, w->name) + tp_assign(val, val) ), TP_printk("widget=%s val=%d", __get_str(name), @@ -239,10 +239,10 @@ TRACE_EVENT(snd_soc_dapm_walk_done, ), TP_fast_assign( - tp_strcpy(name, card->name); - tp_assign(power_checks, card->dapm_stats.power_checks); - tp_assign(path_checks, card->dapm_stats.path_checks); - tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks); + tp_strcpy(name, card->name) + tp_assign(power_checks, card->dapm_stats.power_checks) + tp_assign(path_checks, card->dapm_stats.path_checks) + tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks) ), TP_printk("%s: checks %d power, %d path, %d neighbour", @@ -262,7 +262,7 @@ TRACE_EVENT(snd_soc_jack_irq, ), TP_fast_assign( - tp_strcpy(name, name); + tp_strcpy(name, name) ), TP_printk("%s", __get_str(name)) @@ -281,9 +281,9 @@ TRACE_EVENT(snd_soc_jack_report, ), TP_fast_assign( - tp_strcpy(name, jack->jack->name); - tp_assign(mask, mask); - tp_assign(val, val); + tp_strcpy(name, jack->jack->name) + tp_assign(mask, mask) + tp_assign(val, val) ), TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, @@ -302,8 +302,8 @@ TRACE_EVENT(snd_soc_jack_notify, ), TP_fast_assign( - tp_strcpy(name, jack->jack->name); - tp_assign(val, val); + tp_strcpy(name, jack->jack->name) + tp_assign(val, val) ), TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) @@ -324,10 +324,10 @@ TRACE_EVENT(snd_soc_cache_sync, ), TP_fast_assign( - tp_strcpy(name, codec->name); - tp_strcpy(status, status); - tp_strcpy(type, type); - tp_assign(id, codec->id); + tp_strcpy(name, codec->name) + tp_strcpy(status, status) + tp_strcpy(type, type) + tp_assign(id, codec->id) ), TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h index e02ecf4..de80df9 100644 --- a/instrumentation/events/lttng-module/ext3.h +++ b/instrumentation/events/lttng-module/ext3.h @@ -27,12 +27,12 @@ TRACE_EVENT(ext3_free_inode, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(mode, inode->i_mode); - tp_assign(uid, inode->i_uid); - tp_assign(gid, inode->i_gid); - tp_assign(blocks, inode->i_blocks); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(mode, inode->i_mode) + tp_assign(uid, inode->i_uid) + tp_assign(gid, inode->i_gid) + tp_assign(blocks, inode->i_blocks) ), TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", @@ -54,9 +54,9 @@ TRACE_EVENT(ext3_request_inode, ), TP_fast_assign( - tp_assign(dev, dir->i_sb->s_dev); - tp_assign(dir, dir->i_ino); - tp_assign(mode, mode); + tp_assign(dev, dir->i_sb->s_dev) + tp_assign(dir, dir->i_ino) + tp_assign(mode, mode) ), TP_printk("dev %d,%d dir %lu mode 0%o", @@ -77,10 +77,10 @@ TRACE_EVENT(ext3_allocate_inode, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(dir, dir->i_ino); - tp_assign(mode, mode); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(dir, dir->i_ino) + tp_assign(mode, mode) ), TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", @@ -101,9 +101,9 @@ TRACE_EVENT(ext3_evict_inode, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(nlink, inode->i_nlink); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(nlink, inode->i_nlink) ), TP_printk("dev %d,%d ino %lu nlink %d", @@ -123,9 +123,9 @@ TRACE_EVENT(ext3_drop_inode, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(drop, drop); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(drop, drop) ), TP_printk("dev %d,%d ino %lu drop %d", @@ -145,9 +145,9 @@ TRACE_EVENT(ext3_mark_inode_dirty, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(ip, IP); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(ip, IP) ), TP_printk("dev %d,%d ino %lu caller %pF", @@ -170,11 +170,11 @@ TRACE_EVENT(ext3_write_begin, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(pos, pos); - tp_assign(len, len); - tp_assign(flags, flags); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(pos, pos) + tp_assign(len, len) + tp_assign(flags, flags) ), TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", @@ -199,11 +199,11 @@ DECLARE_EVENT_CLASS(ext3__write_end, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(pos, pos); - tp_assign(len, len); - tp_assign(copied, copied); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(pos, pos) + tp_assign(len, len) + tp_assign(copied, copied) ), TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", @@ -250,9 +250,9 @@ DECLARE_EVENT_CLASS(ext3__page_op, ), TP_fast_assign( - tp_assign(index, page->index); - tp_assign(ino, page->mapping->host->i_ino); - tp_assign(dev, page->mapping->host->i_sb->s_dev); + tp_assign(index, page->index) + tp_assign(ino, page->mapping->host->i_ino) + tp_assign(dev, page->mapping->host->i_sb->s_dev) ), TP_printk("dev %d,%d ino %lu page_index %lu", @@ -309,10 +309,10 @@ TRACE_EVENT(ext3_invalidatepage, ), TP_fast_assign( - tp_assign(index, page->index); - tp_assign(offset, offset); - tp_assign(ino, page->mapping->host->i_ino); - tp_assign(dev, page->mapping->host->i_sb->s_dev); + tp_assign(index, page->index) + tp_assign(offset, offset) + tp_assign(ino, page->mapping->host->i_ino) + tp_assign(dev, page->mapping->host->i_sb->s_dev) ), TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", @@ -335,9 +335,9 @@ TRACE_EVENT(ext3_discard_blocks, ), TP_fast_assign( - tp_assign(dev, sb->s_dev); - tp_assign(blk, blk); - tp_assign(count, count); + tp_assign(dev, sb->s_dev) + tp_assign(blk, blk) + tp_assign(count, count) ), TP_printk("dev %d,%d blk %lu count %lu", @@ -359,10 +359,10 @@ TRACE_EVENT(ext3_request_blocks, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(count, count); - tp_assign(goal, goal); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(count, count) + tp_assign(goal, goal) ), TP_printk("dev %d,%d ino %lu count %lu goal %lu ", @@ -386,11 +386,11 @@ TRACE_EVENT(ext3_allocate_blocks, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(block, block); - tp_assign(count, count); - tp_assign(goal, goal); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(block, block) + tp_assign(count, count) + tp_assign(goal, goal) ), TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", @@ -415,11 +415,11 @@ TRACE_EVENT(ext3_free_blocks, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(mode, inode->i_mode); - tp_assign(block, block); - tp_assign(count, count); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(mode, inode->i_mode) + tp_assign(block, block) + tp_assign(count, count) ), TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", @@ -443,10 +443,10 @@ TRACE_EVENT(ext3_sync_file_enter, TP_fast_assign( dentry = file->f_path.dentry; - tp_assign(dev, dentry->d_inode->i_sb->s_dev); - tp_assign(ino, dentry->d_inode->i_ino); - tp_assign(datasync, datasync); - tp_assign(parent, dentry->d_parent->d_inode->i_ino); + tp_assign(dev, dentry->d_inode->i_sb->s_dev) + tp_assign(ino, dentry->d_inode->i_ino) + tp_assign(datasync, datasync) + tp_assign(parent, dentry->d_parent->d_inode->i_ino) ), TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", @@ -467,9 +467,9 @@ TRACE_EVENT(ext3_sync_file_exit, ), TP_fast_assign( - tp_assign(ret, ret); - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ret, ret) + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) ), TP_printk("dev %d,%d ino %lu ret %d", @@ -490,8 +490,8 @@ TRACE_EVENT(ext3_sync_fs, ), TP_fast_assign( - tp_assign(dev, sb->s_dev); - tp_assign(wait, wait); + tp_assign(dev, sb->s_dev) + tp_assign(wait, wait) ), TP_printk("dev %d,%d wait %d", @@ -512,9 +512,9 @@ TRACE_EVENT(ext3_rsv_window_add, ), TP_fast_assign( - tp_assign(dev, sb->s_dev); - tp_assign(start, rsv_node->rsv_window._rsv_start); - tp_assign(end, rsv_node->rsv_window._rsv_end); + tp_assign(dev, sb->s_dev) + tp_assign(start, rsv_node->rsv_window._rsv_start) + tp_assign(end, rsv_node->rsv_window._rsv_end) ), TP_printk("dev %d,%d start %lu end %lu", @@ -536,10 +536,10 @@ TRACE_EVENT(ext3_discard_reservation, ), TP_fast_assign( - tp_assign(start, rsv_node->rsv_window._rsv_start); - tp_assign(end, rsv_node->rsv_window._rsv_end); - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); + tp_assign(start, rsv_node->rsv_window._rsv_start) + tp_assign(end, rsv_node->rsv_window._rsv_end) + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) ), TP_printk("dev %d,%d ino %lu start %lu end %lu", @@ -559,8 +559,8 @@ TRACE_EVENT(ext3_alloc_new_reservation, ), TP_fast_assign( - tp_assign(dev, sb->s_dev); - tp_assign(goal, goal); + tp_assign(dev, sb->s_dev) + tp_assign(goal, goal) ), TP_printk("dev %d,%d goal %lu", @@ -582,10 +582,10 @@ TRACE_EVENT(ext3_reserved, ), TP_fast_assign( - tp_assign(block, block); - tp_assign(start, rsv_node->rsv_window._rsv_start); - tp_assign(end, rsv_node->rsv_window._rsv_end); - tp_assign(dev, sb->s_dev); + tp_assign(block, block) + tp_assign(start, rsv_node->rsv_window._rsv_start) + tp_assign(end, rsv_node->rsv_window._rsv_end) + tp_assign(dev, sb->s_dev) ), TP_printk("dev %d,%d block %lu, start %lu end %lu", @@ -607,11 +607,11 @@ TRACE_EVENT(ext3_forget, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); - tp_assign(mode, inode->i_mode); - tp_assign(is_metadata, is_metadata); - tp_assign(block, block); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) + tp_assign(mode, inode->i_mode) + tp_assign(is_metadata, is_metadata) + tp_assign(block, block) ), TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", @@ -632,8 +632,8 @@ TRACE_EVENT(ext3_read_block_bitmap, ), TP_fast_assign( - tp_assign(dev, sb->s_dev); - tp_assign(group, group); + tp_assign(dev, sb->s_dev) + tp_assign(group, group) ), TP_printk("dev %d,%d group %u", @@ -655,11 +655,11 @@ TRACE_EVENT(ext3_direct_IO_enter, ), TP_fast_assign( - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(pos, offset); - tp_assign(len, len); - tp_assign(rw, rw); + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(pos, offset) + tp_assign(len, len) + tp_assign(rw, rw) ), TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", @@ -685,12 +685,12 @@ TRACE_EVENT(ext3_direct_IO_exit, ), TP_fast_assign( - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(pos, offset); - tp_assign(len, len); - tp_assign(rw, rw); - tp_assign(ret, ret); + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(pos, offset) + tp_assign(len, len) + tp_assign(rw, rw) + tp_assign(ret, ret) ), TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", @@ -713,10 +713,10 @@ TRACE_EVENT(ext3_unlink_enter, ), TP_fast_assign( - tp_assign(parent, parent->i_ino); - tp_assign(ino, dentry->d_inode->i_ino); - tp_assign(size, dentry->d_inode->i_size); - tp_assign(dev, dentry->d_inode->i_sb->s_dev); + tp_assign(parent, parent->i_ino) + tp_assign(ino, dentry->d_inode->i_ino) + tp_assign(size, dentry->d_inode->i_size) + tp_assign(dev, dentry->d_inode->i_sb->s_dev) ), TP_printk("dev %d,%d ino %lu size %lld parent %ld", @@ -738,9 +738,9 @@ TRACE_EVENT(ext3_unlink_exit, ), TP_fast_assign( - tp_assign(ino, dentry->d_inode->i_ino); - tp_assign(dev, dentry->d_inode->i_sb->s_dev); - tp_assign(ret, ret); + tp_assign(ino, dentry->d_inode->i_ino) + tp_assign(dev, dentry->d_inode->i_sb->s_dev) + tp_assign(ret, ret) ), TP_printk("dev %d,%d ino %lu ret %d", @@ -761,9 +761,9 @@ DECLARE_EVENT_CLASS(ext3__truncate, ), TP_fast_assign( - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(blocks, inode->i_blocks); + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(blocks, inode->i_blocks) ), TP_printk("dev %d,%d ino %lu blocks %lu", @@ -800,11 +800,11 @@ TRACE_EVENT(ext3_get_blocks_enter, ), TP_fast_assign( - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(lblk, lblk); - tp_assign(len, len); - tp_assign(create, create); + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(lblk, lblk) + tp_assign(len, len) + tp_assign(create, create) ), TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", @@ -829,12 +829,12 @@ TRACE_EVENT(ext3_get_blocks_exit, ), TP_fast_assign( - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(lblk, lblk); - tp_assign(pblk, pblk); - tp_assign(len, len); - tp_assign(ret, ret); + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(lblk, lblk) + tp_assign(pblk, pblk) + tp_assign(len, len) + tp_assign(ret, ret) ), TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", @@ -855,8 +855,8 @@ TRACE_EVENT(ext3_load_inode, ), TP_fast_assign( - tp_assign(ino, inode->i_ino); - tp_assign(dev, inode->i_sb->s_dev); + tp_assign(ino, inode->i_ino) + tp_assign(dev, inode->i_sb->s_dev) ), TP_printk("dev %d,%d ino %lu", diff --git a/instrumentation/events/lttng-module/gpio.h b/instrumentation/events/lttng-module/gpio.h index e6002c4..a0c5876 100644 --- a/instrumentation/events/lttng-module/gpio.h +++ b/instrumentation/events/lttng-module/gpio.h @@ -19,9 +19,9 @@ TRACE_EVENT(gpio_direction, ), TP_fast_assign( - tp_assign(gpio, gpio); - tp_assign(in, in); - tp_assign(err, err); + tp_assign(gpio, gpio) + tp_assign(in, in) + tp_assign(err, err) ), TP_printk("%u %3s (%d)", __entry->gpio, @@ -41,9 +41,9 @@ TRACE_EVENT(gpio_value, ), TP_fast_assign( - tp_assign(gpio, gpio); - tp_assign(get, get); - tp_assign(value, value); + tp_assign(gpio, gpio) + tp_assign(get, get) + tp_assign(value, value) ), TP_printk("%u %3s %d", __entry->gpio, diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h index 97ba1e5..b6bd64a 100644 --- a/instrumentation/events/lttng-module/jbd.h +++ b/instrumentation/events/lttng-module/jbd.h @@ -19,8 +19,8 @@ TRACE_EVENT(jbd_checkpoint, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(result, result); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(result, result) ), TP_printk("dev %d,%d result %d", @@ -43,11 +43,11 @@ DECLARE_EVENT_CLASS(jbd_commit, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(dev, journal->j_fs_dev->bd_dev) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) #endif - tp_assign(transaction, commit_transaction->t_tid); + tp_assign(transaction, commit_transaction->t_tid) ), #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) @@ -104,11 +104,11 @@ TRACE_EVENT(jbd_drop_transaction, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(dev, journal->j_fs_dev->bd_dev) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) #endif - tp_assign(transaction, commit_transaction->t_tid); + tp_assign(transaction, commit_transaction->t_tid) ), #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) @@ -137,12 +137,12 @@ TRACE_EVENT(jbd_end_commit, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(dev, journal->j_fs_dev->bd_dev) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) #endif - tp_assign(transaction, commit_transaction->t_tid); - tp_assign(head, journal->j_tail_sequence); + tp_assign(transaction, commit_transaction->t_tid) + tp_assign(head, journal->j_tail_sequence) ), #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) @@ -170,11 +170,11 @@ TRACE_EVENT(jbd_do_submit_data, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); + tp_assign(dev, journal->j_fs_dev->bd_dev) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) #endif - tp_assign(transaction, commit_transaction->t_tid); + tp_assign(transaction, commit_transaction->t_tid) ), #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) @@ -204,11 +204,11 @@ TRACE_EVENT(jbd_cleanup_journal_tail, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(tail_sequence, journal->j_tail_sequence); - tp_assign(first_tid, first_tid); - tp_assign(block_nr, block_nr); - tp_assign(freed, freed); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(tail_sequence, journal->j_tail_sequence) + tp_assign(first_tid, first_tid) + tp_assign(block_nr, block_nr) + tp_assign(freed, freed) ), TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", @@ -228,8 +228,8 @@ TRACE_EVENT(jbd_update_superblock_end, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(wait, wait); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(wait, wait) ), TP_printk("dev %d,%d wait %d", diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h index 2e80832..91e2e6c 100644 --- a/instrumentation/events/lttng-module/jbd2.h +++ b/instrumentation/events/lttng-module/jbd2.h @@ -148,16 +148,16 @@ TRACE_EVENT(jbd2_run_stats, ), TP_fast_assign( - tp_assign(dev, dev); - tp_assign(tid, tid); - tp_assign(wait, stats->rs_wait); - tp_assign(running, stats->rs_running); - tp_assign(locked, stats->rs_locked); - tp_assign(flushing, stats->rs_flushing); - tp_assign(logging, stats->rs_logging); - tp_assign(handle_count, stats->rs_handle_count); - tp_assign(blocks, stats->rs_blocks); - tp_assign(blocks_logged, stats->rs_blocks_logged); + tp_assign(dev, dev) + tp_assign(tid, tid) + tp_assign(wait, stats->rs_wait) + tp_assign(running, stats->rs_running) + tp_assign(locked, stats->rs_locked) + tp_assign(flushing, stats->rs_flushing) + tp_assign(logging, stats->rs_logging) + tp_assign(handle_count, stats->rs_handle_count) + tp_assign(blocks, stats->rs_blocks) + tp_assign(blocks_logged, stats->rs_blocks_logged) ), TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " @@ -188,12 +188,12 @@ TRACE_EVENT(jbd2_checkpoint_stats, ), TP_fast_assign( - tp_assign(dev, dev); - tp_assign(tid, tid); - tp_assign(chp_time, stats->cs_chp_time); - tp_assign(forced_to_close, stats->cs_forced_to_close); - tp_assign(written, stats->cs_written); - tp_assign(dropped, stats->cs_dropped); + tp_assign(dev, dev) + tp_assign(tid, tid) + tp_assign(chp_time, stats->cs_chp_time) + tp_assign(forced_to_close, stats->cs_forced_to_close) + tp_assign(written, stats->cs_written) + tp_assign(dropped, stats->cs_dropped) ), TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " @@ -219,11 +219,11 @@ TRACE_EVENT(jbd2_cleanup_journal_tail, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(tail_sequence, journal->j_tail_sequence); - tp_assign(first_tid, first_tid); - tp_assign(block_nr, block_nr); - tp_assign(freed, freed); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(tail_sequence, journal->j_tail_sequence) + tp_assign(first_tid, first_tid) + tp_assign(block_nr, block_nr) + tp_assign(freed, freed) ), TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h index 04f668b..dab8989 100644 --- a/instrumentation/events/lttng-module/kmem.h +++ b/instrumentation/events/lttng-module/kmem.h @@ -23,11 +23,11 @@ DECLARE_EVENT_CLASS(kmem_alloc, ), TP_fast_assign( - tp_assign(call_site, call_site); - tp_assign(ptr, ptr); - tp_assign(bytes_req, bytes_req); - tp_assign(bytes_alloc, bytes_alloc); - tp_assign(gfp_flags, gfp_flags); + tp_assign(call_site, call_site) + tp_assign(ptr, ptr) + tp_assign(bytes_req, bytes_req) + tp_assign(bytes_alloc, bytes_alloc) + tp_assign(gfp_flags, gfp_flags) ), TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", @@ -75,12 +75,12 @@ DECLARE_EVENT_CLASS(kmem_alloc_node, ), TP_fast_assign( - tp_assign(call_site, call_site); - tp_assign(ptr, ptr); - tp_assign(bytes_req, bytes_req); - tp_assign(bytes_alloc, bytes_alloc); - tp_assign(gfp_flags, gfp_flags); - tp_assign(node, node); + tp_assign(call_site, call_site) + tp_assign(ptr, ptr) + tp_assign(bytes_req, bytes_req) + tp_assign(bytes_alloc, bytes_alloc) + tp_assign(gfp_flags, gfp_flags) + tp_assign(node, node) ), TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", @@ -122,8 +122,8 @@ DECLARE_EVENT_CLASS(kmem_free, ), TP_fast_assign( - tp_assign(call_site, call_site); - tp_assign(ptr, ptr); + tp_assign(call_site, call_site) + tp_assign(ptr, ptr) ), TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) @@ -155,8 +155,8 @@ TRACE_EVENT(mm_page_free_direct, ), TP_fast_assign( - tp_assign(page, page); - tp_assign(order, order); + tp_assign(page, page) + tp_assign(order, order) ), TP_printk("page=%p pfn=%lu order=%d", @@ -177,8 +177,8 @@ TRACE_EVENT(mm_pagevec_free, ), TP_fast_assign( - tp_assign(page, page); - tp_assign(cold, cold); + tp_assign(page, page) + tp_assign(cold, cold) ), TP_printk("page=%p pfn=%lu order=0 cold=%d", @@ -202,10 +202,10 @@ TRACE_EVENT(mm_page_alloc, ), TP_fast_assign( - tp_assign(page, page); - tp_assign(order, order); - tp_assign(gfp_flags, gfp_flags); - tp_assign(migratetype, migratetype); + tp_assign(page, page) + tp_assign(order, order) + tp_assign(gfp_flags, gfp_flags) + tp_assign(migratetype, migratetype) ), TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", @@ -229,9 +229,9 @@ DECLARE_EVENT_CLASS(mm_page, ), TP_fast_assign( - tp_assign(page, page); - tp_assign(order, order); - tp_assign(migratetype, migratetype); + tp_assign(page, page) + tp_assign(order, order) + tp_assign(migratetype, migratetype) ), TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", @@ -279,11 +279,11 @@ TRACE_EVENT(mm_page_alloc_extfrag, ), TP_fast_assign( - tp_assign(page, page); - tp_assign(alloc_order, alloc_order); - tp_assign(fallback_order, fallback_order); - tp_assign(alloc_migratetype, alloc_migratetype); - tp_assign(fallback_migratetype, fallback_migratetype); + tp_assign(page, page) + tp_assign(alloc_order, alloc_order) + tp_assign(fallback_order, fallback_order) + tp_assign(alloc_migratetype, alloc_migratetype) + tp_assign(fallback_migratetype, fallback_migratetype) ), TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", diff --git a/instrumentation/events/lttng-module/lock.h b/instrumentation/events/lttng-module/lock.h index 75101f6..e2c1c7a 100644 --- a/instrumentation/events/lttng-module/lock.h +++ b/instrumentation/events/lttng-module/lock.h @@ -24,9 +24,9 @@ TRACE_EVENT(lock_acquire, ), TP_fast_assign( - tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)); - tp_strcpy(name, lock->name); - tp_assign(lockdep_addr, lock); + tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)) + tp_strcpy(name, lock->name) + tp_assign(lockdep_addr, lock) ), TP_printk("%p %s%s%s", __entry->lockdep_addr, @@ -47,8 +47,8 @@ DECLARE_EVENT_CLASS(lock, ), TP_fast_assign( - tp_strcpy(name, lock->name); - tp_assign(lockdep_addr, lock); + tp_strcpy(name, lock->name) + tp_assign(lockdep_addr, lock) ), TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) diff --git a/instrumentation/events/lttng-module/module.h b/instrumentation/events/lttng-module/module.h index 2e83431..65a8135 100644 --- a/instrumentation/events/lttng-module/module.h +++ b/instrumentation/events/lttng-module/module.h @@ -40,8 +40,8 @@ TRACE_EVENT(module_load, ), TP_fast_assign( - tp_assign(taints, mod->taints); - tp_strcpy(name, mod->name); + tp_assign(taints, mod->taints) + tp_strcpy(name, mod->name) ), TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) @@ -58,7 +58,7 @@ TRACE_EVENT(module_free, ), TP_fast_assign( - tp_strcpy(name, mod->name); + tp_strcpy(name, mod->name) ), TP_printk("%s", __get_str(name)) @@ -80,9 +80,9 @@ DECLARE_EVENT_CLASS(module_refcnt, ), TP_fast_assign( - tp_assign(ip, ip); - tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)); - tp_strcpy(name, mod->name); + tp_assign(ip, ip) + tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)) + tp_strcpy(name, mod->name) ), TP_printk("%s call_site=%pf refcnt=%d", @@ -117,9 +117,9 @@ TRACE_EVENT(module_request, ), TP_fast_assign( - tp_assign(ip, ip); - tp_assign(wait, wait); - tp_strcpy(name, name); + tp_assign(ip, ip) + tp_assign(wait, wait) + tp_strcpy(name, name) ), TP_printk("%s wait=%d call_site=%pf", diff --git a/instrumentation/events/lttng-module/napi.h b/instrumentation/events/lttng-module/napi.h index 58b8336..26b10ba 100644 --- a/instrumentation/events/lttng-module/napi.h +++ b/instrumentation/events/lttng-module/napi.h @@ -22,8 +22,8 @@ TRACE_EVENT(napi_poll, ), TP_fast_assign( - tp_assign(napi, napi); - tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV); + tp_assign(napi, napi) + tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV) ), TP_printk("napi poll on napi struct %p for device %s", diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h index 589011c..a444b07 100644 --- a/instrumentation/events/lttng-module/net.h +++ b/instrumentation/events/lttng-module/net.h @@ -39,17 +39,17 @@ TRACE_EVENT(net_dev_xmit, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) TP_fast_assign( - tp_assign(skbaddr, skb); - tp_assign(len, skb_len); - tp_assign(rc, rc); - tp_strcpy(name, dev->name); + tp_assign(skbaddr, skb) + tp_assign(len, skb_len) + tp_assign(rc, rc) + tp_strcpy(name, dev->name) ), #else TP_fast_assign( - tp_assign(skbaddr, skb); - tp_assign(len, skb->len); - tp_assign(rc, rc); - tp_strcpy(name, skb->dev->name); + tp_assign(skbaddr, skb) + tp_assign(len, skb->len) + tp_assign(rc, rc) + tp_strcpy(name, skb->dev->name) ), #endif @@ -70,9 +70,9 @@ DECLARE_EVENT_CLASS(net_dev_template, ), TP_fast_assign( - tp_assign(skbaddr, skb); - tp_assign(len, skb->len); - tp_strcpy(name, skb->dev->name); + tp_assign(skbaddr, skb) + tp_assign(len, skb->len) + tp_strcpy(name, skb->dev->name) ), TP_printk("dev=%s skbaddr=%p len=%u", diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h index 05aced7..f2e3f54 100644 --- a/instrumentation/events/lttng-module/power.h +++ b/instrumentation/events/lttng-module/power.h @@ -19,8 +19,8 @@ DECLARE_EVENT_CLASS(cpu, ), TP_fast_assign( - tp_assign(state, state); - tp_assign(cpu_id, cpu_id); + tp_assign(state, state) + tp_assign(cpu_id, cpu_id) ), TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, @@ -59,7 +59,7 @@ TRACE_EVENT(machine_suspend, ), TP_fast_assign( - tp_assign(state, state); + tp_assign(state, state) ), TP_printk("state=%lu", (unsigned long)__entry->state) @@ -85,9 +85,9 @@ DECLARE_EVENT_CLASS(power, ), TP_fast_assign( - tp_assign(type, type); - tp_assign(state, state); - tp_assign(cpu_id, cpu_id); + tp_assign(type, type) + tp_assign(state, state) + tp_assign(cpu_id, cpu_id) ), TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, @@ -119,7 +119,7 @@ TRACE_EVENT(power_end, ), TP_fast_assign( - tp_assign(cpu_id, cpu_id); + tp_assign(cpu_id, cpu_id) ), TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) @@ -173,9 +173,9 @@ DECLARE_EVENT_CLASS(clock, ), TP_fast_assign( - tp_strcpy(name, name); - tp_assign(state, state); - tp_assign(cpu_id, cpu_id); + tp_strcpy(name, name) + tp_assign(state, state) + tp_assign(cpu_id, cpu_id) ), TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), @@ -219,9 +219,9 @@ DECLARE_EVENT_CLASS(power_domain, ), TP_fast_assign( - tp_strcpy(name, name); - tp_assign(state, state); - tp_assign(cpu_id, cpu_id); + tp_strcpy(name, name) + tp_assign(state, state) + tp_assign(cpu_id, cpu_id) ), TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), diff --git a/instrumentation/events/lttng-module/regulator.h b/instrumentation/events/lttng-module/regulator.h index e94da7c..bb84c47 100644 --- a/instrumentation/events/lttng-module/regulator.h +++ b/instrumentation/events/lttng-module/regulator.h @@ -22,7 +22,7 @@ DECLARE_EVENT_CLASS(regulator_basic, ), TP_fast_assign( - tp_strcpy(name, name); + tp_strcpy(name, name) ), TP_printk("name=%s", __get_str(name)) @@ -86,9 +86,9 @@ DECLARE_EVENT_CLASS(regulator_range, ), TP_fast_assign( - tp_strcpy(name, name); - tp_assign(min, min); - tp_assign(max, max); + tp_strcpy(name, name) + tp_assign(min, min) + tp_assign(max, max) ), TP_printk("name=%s (%d-%d)", __get_str(name), @@ -119,8 +119,8 @@ DECLARE_EVENT_CLASS(regulator_value, ), TP_fast_assign( - tp_strcpy(name, name); - tp_assign(val, val); + tp_strcpy(name, name) + tp_assign(val, val) ), TP_printk("name=%s, val=%u", __get_str(name), diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h index 27362f8..18d2b02 100644 --- a/instrumentation/events/lttng-module/scsi.h +++ b/instrumentation/events/lttng-module/scsi.h @@ -222,16 +222,16 @@ TRACE_EVENT(scsi_dispatch_cmd_start, ), TP_fast_assign( - tp_assign(host_no, cmd->device->host->host_no); - tp_assign(channel, cmd->device->channel); - tp_assign(id, cmd->device->id); - tp_assign(lun, cmd->device->lun); - tp_assign(opcode, cmd->cmnd[0]); - tp_assign(cmd_len, cmd->cmd_len); - tp_assign(data_sglen, scsi_sg_count(cmd)); - tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); - tp_assign(prot_op, scsi_get_prot_op(cmd)); - tp_memcpy_dyn(cmnd, cmd->cmnd); + tp_assign(host_no, cmd->device->host->host_no) + tp_assign(channel, cmd->device->channel) + tp_assign(id, cmd->device->id) + tp_assign(lun, cmd->device->lun) + tp_assign(opcode, cmd->cmnd[0]) + tp_assign(cmd_len, cmd->cmd_len) + tp_assign(data_sglen, scsi_sg_count(cmd)) + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) + tp_assign(prot_op, scsi_get_prot_op(cmd)) + tp_memcpy_dyn(cmnd, cmd->cmnd) ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ @@ -265,17 +265,17 @@ TRACE_EVENT(scsi_dispatch_cmd_error, ), TP_fast_assign( - tp_assign(host_no, cmd->device->host->host_no); - tp_assign(channel, cmd->device->channel); - tp_assign(id, cmd->device->id); - tp_assign(lun, cmd->device->lun); - tp_assign(rtn, rtn); - tp_assign(opcode, cmd->cmnd[0]); - tp_assign(cmd_len, cmd->cmd_len); - tp_assign(data_sglen, scsi_sg_count(cmd)); - tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); - tp_assign(prot_op, scsi_get_prot_op(cmd)); - tp_memcpy_dyn(cmnd, cmd->cmnd); + tp_assign(host_no, cmd->device->host->host_no) + tp_assign(channel, cmd->device->channel) + tp_assign(id, cmd->device->id) + tp_assign(lun, cmd->device->lun) + tp_assign(rtn, rtn) + tp_assign(opcode, cmd->cmnd[0]) + tp_assign(cmd_len, cmd->cmd_len) + tp_assign(data_sglen, scsi_sg_count(cmd)) + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) + tp_assign(prot_op, scsi_get_prot_op(cmd)) + tp_memcpy_dyn(cmnd, cmd->cmnd) ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ @@ -310,17 +310,17 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, ), TP_fast_assign( - tp_assign(host_no, cmd->device->host->host_no); - tp_assign(channel, cmd->device->channel); - tp_assign(id, cmd->device->id); - tp_assign(lun, cmd->device->lun); - tp_assign(result, cmd->result); - tp_assign(opcode, cmd->cmnd[0]); - tp_assign(cmd_len, cmd->cmd_len); - tp_assign(data_sglen, scsi_sg_count(cmd)); - tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); - tp_assign(prot_op, scsi_get_prot_op(cmd)); - tp_memcpy_dyn(cmnd, cmd->cmnd); + tp_assign(host_no, cmd->device->host->host_no) + tp_assign(channel, cmd->device->channel) + tp_assign(id, cmd->device->id) + tp_assign(lun, cmd->device->lun) + tp_assign(result, cmd->result) + tp_assign(opcode, cmd->cmnd[0]) + tp_assign(cmd_len, cmd->cmd_len) + tp_assign(data_sglen, scsi_sg_count(cmd)) + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) + tp_assign(prot_op, scsi_get_prot_op(cmd)) + tp_memcpy_dyn(cmnd, cmd->cmnd) ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ @@ -357,7 +357,7 @@ TRACE_EVENT(scsi_eh_wakeup, ), TP_fast_assign( - tp_assign(host_no, shost->host_no); + tp_assign(host_no, shost->host_no) ), TP_printk("host_no=%u", __entry->host_no) diff --git a/instrumentation/events/lttng-module/skb.h b/instrumentation/events/lttng-module/skb.h index 9a79449..3163356 100644 --- a/instrumentation/events/lttng-module/skb.h +++ b/instrumentation/events/lttng-module/skb.h @@ -24,9 +24,9 @@ TRACE_EVENT(kfree_skb, ), TP_fast_assign( - tp_assign(skbaddr, skb); - tp_assign(location, location); - tp_assign(protocol, ntohs(skb->protocol)); + tp_assign(skbaddr, skb) + tp_assign(location, location) + tp_assign(protocol, ntohs(skb->protocol)) ), TP_printk("skbaddr=%p protocol=%u location=%p", @@ -44,7 +44,7 @@ TRACE_EVENT(consume_skb, ), TP_fast_assign( - tp_assign(skbaddr, skb); + tp_assign(skbaddr, skb) ), TP_printk("skbaddr=%p", __entry->skbaddr) @@ -62,8 +62,8 @@ TRACE_EVENT(skb_copy_datagram_iovec, ), TP_fast_assign( - tp_assign(skbaddr, skb); - tp_assign(len, len); + tp_assign(skbaddr, skb) + tp_assign(len, len) ), TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h index 246ea58..c4e689a 100644 --- a/instrumentation/events/lttng-module/sock.h +++ b/instrumentation/events/lttng-module/sock.h @@ -20,9 +20,9 @@ TRACE_EVENT(sock_rcvqueue_full, ), TP_fast_assign( - tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); - tp_assign(truesize, skb->truesize); - tp_assign(sk_rcvbuf, sk->sk_rcvbuf); + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)) + tp_assign(truesize, skb->truesize) + tp_assign(sk_rcvbuf, sk->sk_rcvbuf) ), TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", @@ -44,10 +44,10 @@ TRACE_EVENT(sock_exceed_buf_limit, ), TP_fast_assign( - tp_strcpy(name, prot->name); - tp_assign(sysctl_mem, prot->sysctl_mem); - tp_assign(allocated, allocated); - tp_assign(sysctl_rmem, prot->sysctl_rmem[0]); + tp_strcpy(name, prot->name) + tp_assign(sysctl_mem, prot->sysctl_mem) + tp_assign(allocated, allocated) + tp_assign(sysctl_rmem, prot->sysctl_rmem[0]) tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); ), diff --git a/instrumentation/events/lttng-module/udp.h b/instrumentation/events/lttng-module/udp.h index 304ea95..a246e84 100644 --- a/instrumentation/events/lttng-module/udp.h +++ b/instrumentation/events/lttng-module/udp.h @@ -19,8 +19,8 @@ TRACE_EVENT(udp_fail_queue_rcv_skb, ), TP_fast_assign( - tp_assign(rc, rc); - tp_assign(lport, inet_sk(sk)->inet_num); + tp_assign(rc, rc) + tp_assign(lport, inet_sk(sk)->inet_num) ), TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h index aa022e2..d6ab952 100644 --- a/instrumentation/events/lttng-module/vmscan.h +++ b/instrumentation/events/lttng-module/vmscan.h @@ -15,7 +15,7 @@ TRACE_EVENT(mm_vmscan_kswapd_sleep, ), TP_fast_assign( - tp_assign(nid, nid); + tp_assign(nid, nid) ), TP_printk("nid=%d", __entry->nid) @@ -33,8 +33,8 @@ TRACE_EVENT(mm_vmscan_kswapd_wake, ), TP_fast_assign( - tp_assign(nid, nid); - tp_assign(order, order); + tp_assign(nid, nid) + tp_assign(order, order) ), TP_printk("nid=%d order=%d", __entry->nid, __entry->order) @@ -53,9 +53,9 @@ TRACE_EVENT(mm_vmscan_wakeup_kswapd, ), TP_fast_assign( - tp_assign(nid, nid); - tp_assign(zid, zid); - tp_assign(order, order); + tp_assign(nid, nid) + tp_assign(zid, zid) + tp_assign(order, order) ), TP_printk("nid=%d zid=%d order=%d", @@ -77,9 +77,9 @@ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, ), TP_fast_assign( - tp_assign(order, order); - tp_assign(may_writepage, may_writepage); - tp_assign(gfp_flags, gfp_flags); + tp_assign(order, order) + tp_assign(may_writepage, may_writepage) + tp_assign(gfp_flags, gfp_flags) ), TP_printk("order=%d may_writepage=%d gfp_flags=%s", @@ -120,7 +120,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, ), TP_fast_assign( - tp_assign(nr_reclaimed, nr_reclaimed); + tp_assign(nr_reclaimed, nr_reclaimed) ), TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) @@ -169,15 +169,15 @@ TRACE_EVENT(mm_shrink_slab_start, ), TP_fast_assign( - tp_assign(shr,shr); - tp_assign(shrink, shr->shrink); - tp_assign(nr_objects_to_shrink, nr_objects_to_shrink); - tp_assign(gfp_flags, sc->gfp_mask); - tp_assign(pgs_scanned, pgs_scanned); - tp_assign(lru_pgs, lru_pgs); - tp_assign(cache_items, cache_items); - tp_assign(delta, delta); - tp_assign(total_scan, total_scan); + tp_assign(shr,shr) + tp_assign(shrink, shr->shrink) + tp_assign(nr_objects_to_shrink, nr_objects_to_shrink) + tp_assign(gfp_flags, sc->gfp_mask) + tp_assign(pgs_scanned, pgs_scanned) + tp_assign(lru_pgs, lru_pgs) + tp_assign(cache_items, cache_items) + tp_assign(delta, delta) + tp_assign(total_scan, total_scan) ), TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", @@ -208,12 +208,12 @@ TRACE_EVENT(mm_shrink_slab_end, ), TP_fast_assign( - tp_assign(shr, shr); - tp_assign(shrink, shr->shrink); - tp_assign(unused_scan, unused_scan_cnt); - tp_assign(new_scan, new_scan_cnt); - tp_assign(retval, shrinker_retval); - tp_assign(total_scan, new_scan_cnt - unused_scan_cnt); + tp_assign(shr, shr) + tp_assign(shrink, shr->shrink) + tp_assign(unused_scan, unused_scan_cnt) + tp_assign(new_scan, new_scan_cnt) + tp_assign(retval, shrinker_retval) + tp_assign(total_scan, new_scan_cnt - unused_scan_cnt) ), TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", @@ -262,16 +262,16 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, ), TP_fast_assign( - tp_assign(order, order); - tp_assign(nr_requested, nr_requested); - tp_assign(nr_scanned, nr_scanned); - tp_assign(nr_taken, nr_taken); - tp_assign(nr_lumpy_taken, nr_lumpy_taken); - tp_assign(nr_lumpy_dirty, nr_lumpy_dirty); - tp_assign(nr_lumpy_failed, nr_lumpy_failed); - tp_assign(isolate_mode, isolate_mode); + tp_assign(order, order) + tp_assign(nr_requested, nr_requested) + tp_assign(nr_scanned, nr_scanned) + tp_assign(nr_taken, nr_taken) + tp_assign(nr_lumpy_taken, nr_lumpy_taken) + tp_assign(nr_lumpy_dirty, nr_lumpy_dirty) + tp_assign(nr_lumpy_failed, nr_lumpy_failed) + tp_assign(isolate_mode, isolate_mode) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) - tp_assign(file, file); + tp_assign(file, file) #endif ), @@ -364,8 +364,8 @@ TRACE_EVENT(mm_vmscan_writepage, ), TP_fast_assign( - tp_assign(page, page); - tp_assign(reclaim_flags, reclaim_flags); + tp_assign(page, page) + tp_assign(reclaim_flags, reclaim_flags) ), TP_printk("page=%p pfn=%lu flags=%s", @@ -392,12 +392,12 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, ), TP_fast_assign( - tp_assign(nid, nid); - tp_assign(zid, zid); - tp_assign(nr_scanned, nr_scanned); - tp_assign(nr_reclaimed, nr_reclaimed); - tp_assign(priority, priority); - tp_assign(reclaim_flags, reclaim_flags); + tp_assign(nid, nid) + tp_assign(zid, zid) + tp_assign(nr_scanned, nr_scanned) + tp_assign(nr_reclaimed, nr_reclaimed) + tp_assign(priority, priority) + tp_assign(reclaim_flags, reclaim_flags) ), TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", @@ -423,10 +423,10 @@ TRACE_EVENT(replace_swap_token, ), TP_fast_assign( - tp_assign(old_mm, old_mm); - tp_assign(old_prio, old_mm ? old_mm->token_priority : 0); - tp_assign(new_mm, new_mm); - tp_assign(new_prio, new_mm->token_priority); + tp_assign(old_mm, old_mm) + tp_assign(old_prio, old_mm ? old_mm->token_priority : 0) + tp_assign(new_mm, new_mm) + tp_assign(new_prio, new_mm->token_priority) ), TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", @@ -444,7 +444,7 @@ DECLARE_EVENT_CLASS(put_swap_token_template, ), TP_fast_assign( - tp_assign(swap_token_mm, swap_token_mm); + tp_assign(swap_token_mm, swap_token_mm) ), TP_printk("token_mm=%p", __entry->swap_token_mm) @@ -479,11 +479,11 @@ TRACE_EVENT_CONDITION(update_swap_token_priority, ), TP_fast_assign( - tp_assign(mm, mm); - tp_assign(old_prio, old_prio); - tp_assign(new_prio, mm->token_priority); - tp_assign(swap_token_mm, swap_token_mm); - tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0); + tp_assign(mm, mm) + tp_assign(old_prio, old_prio) + tp_assign(new_prio, mm->token_priority) + tp_assign(swap_token_mm, swap_token_mm) + tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0) ), TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", -- 1.7.10.4 From Paul_Woegerer at mentor.com Wed Nov 14 07:55:59 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Wed, 14 Nov 2012 13:55:59 +0100 Subject: [lttng-dev] [PATCH lttng-tools] Enable additional kernel probes Message-ID: <50A394DF.70607@mentor.com> To enable the extra kernel probes (see related thread: http://lists.lttng.org/pipermail/lttng-dev/2012-November/019046.html) the following patch is required for lttng-tools: >From fbf7bdae4af6d082ce71bc0976628e5d24a515fc Mon Sep 17 00:00:00 2001 From: Paul Woegerer Date: Wed, 14 Nov 2012 13:49:45 +0100 Subject: [PATCH] Add additional kernel probes to module list. --- src/bin/lttng-sessiond/modprobe.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c index b3f2e57..f38d393 100644 --- a/src/bin/lttng-sessiond/modprobe.c +++ b/src/bin/lttng-sessiond/modprobe.c @@ -44,13 +44,30 @@ const struct kern_modules_param kern_modules_list[] = { { "lttng-ring-buffer-metadata-mmap-client", 1 }, { "lttng-probe-lttng", 1 }, { "lttng-types", 0 }, + { "lttng-probe-asoc", 0 }, { "lttng-probe-block", 0 }, + { "lttng-probe-ext3", 0 }, + { "lttng-probe-gpio", 0 }, { "lttng-probe-irq", 0 }, + { "lttng-probe-jbd", 0 }, + { "lttng-probe-jbd2", 0 }, + { "lttng-probe-kmem", 0 }, { "lttng-probe-kvm", 0 }, + { "lttng-probe-lock", 0 }, + { "lttng-probe-modules", 0 }, + { "lttng-probe-napi", 0 }, + { "lttng-probe-net", 0 }, + { "lttng-probe-power", 0 }, + { "lttng-probe-regulator", 0 }, { "lttng-probe-sched", 0 }, + { "lttng-probe-scsi", 0 }, { "lttng-probe-signal", 0 }, + { "lttng-probe-skb", 0 }, + { "lttng-probe-sock", 0 }, { "lttng-probe-statedump", 0 }, { "lttng-probe-timer", 0 }, + { "lttng-probe-udp", 0 }, + { "lttng-probe-vmscan", 0 }, }; /* -- 1.7.10.4 -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From blackhole37 at gmail.com Wed Nov 14 04:41:52 2012 From: blackhole37 at gmail.com (Vince Do) Date: Wed, 14 Nov 2012 10:41:52 +0100 Subject: [lttng-dev] Timestamps in kernel tracing with LTTng Message-ID: Hello, I was wondering if you can give me more information on how LTTng the timestamps are taken for a kernel trace, I have read in this article (Combined Tracing of the Kernel and Applications with LTTng at Linux Symposium 2009) that TSC and the command rdtsc are used, but the article is old (2009) and I would like to know if there are been any changes. Regards, Vincenzo Do -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Wed Nov 14 10:21:12 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 14 Nov 2012 10:21:12 -0500 Subject: [lttng-dev] Timestamps in kernel tracing with LTTng In-Reply-To: References: Message-ID: <20121114152112.GA31776@Krystal> * Vince Do (blackhole37 at gmail.com) wrote: > Hello, > > I was wondering if you can give me more information on how LTTng the > timestamps are taken for a kernel trace, I have read in this article > (Combined Tracing of the Kernel and Applications with LTTng at Linux > Symposium 2009) that TSC and the command rdtsc are used, but the article is > old (2009) and I would like to know if there are been any changes. lttng uses the Linux kernel CLOCK_MONOTONIC clock, read through clock_gettime() in user-space, and from ktime_get() in the kernel. On x86 systems where TSC are synchronized and constant, it uses rdtsc, scales that value to nanoseconds, and adds an offset. The fall-back is usually the HPET timer on x86. Thanks, Mathieu > > Regards, > > > > Vincenzo Do > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 14 10:43:58 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 14 Nov 2012 10:43:58 -0500 Subject: [lttng-dev] Broken links on lttng.org In-Reply-To: <20998D40D9A2B7499CA5A3A2666CB1EB19F86D7E@ZURMSG1.QUANTUM.com> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F86D7E@ZURMSG1.QUANTUM.com> Message-ID: <20121114154358.GA32183@Krystal> Hi David, Thanks for reporting, forwaring to Christian and Alexandre. Mathieu * David OShea (David.OShea at quantum.com) wrote: > Hi all, > > I noticed that a number of things were broken on the website in the last few weeks: > > 1. At http://lttng.org/documentation, the five man page links at the top are broken (return "Page not found"). I haven't tried other links on that page. > > 2. http://lttng.org/tracingwiki/index.php/ is now broken ("Page not found"). I can't remember what used to be in that wiki, or how I found it, but I seem to remember it being useful :) > > Thanks in advance, > David > > ---------------------------------------------------------------------- > The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From alexandre.montplaisir at polymtl.ca Wed Nov 14 11:03:27 2012 From: alexandre.montplaisir at polymtl.ca (Alexandre Montplaisir) Date: Wed, 14 Nov 2012 11:03:27 -0500 Subject: [lttng-dev] Broken links on lttng.org In-Reply-To: <20121114154358.GA32183@Krystal> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F86D7E@ZURMSG1.QUANTUM.com> <20121114154358.GA32183@Krystal> Message-ID: <50A3C0CF.6010408@polymtl.ca> On 12-11-14 10:43 AM, Mathieu Desnoyers wrote: > Hi David, > > Thanks for reporting, forwaring to Christian and Alexandre. > > Mathieu > > * David OShea (David.OShea at quantum.com) wrote: >> Hi all, >> >> I noticed that a number of things were broken on the website in the last few weeks: >> >> 1. At http://lttng.org/documentation, the five man page links at the top are broken (return "Page not found"). I haven't tried other links on that page. Hmm, a symlink got deleted at some point... Fixed. Thanks for letting us know! >> >> 2. http://lttng.org/tracingwiki/index.php/ is now broken ("Page not found"). I can't remember what used to be in that wiki, or how I found it, but I seem to remember it being useful :) That wiki got removed since it was sorely unmaintained, but the idea was to migrate any existing/useful information to the lttng.org website itself. Yannick, do you know what happened to it? Cheers, -- Alexandre Montplaisir DORSAL lab, ?cole Polytechnique de Montr?al From mathieu.desnoyers at efficios.com Wed Nov 14 11:07:37 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 14 Nov 2012 11:07:37 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Additional kernel probes In-Reply-To: <50A36A7E.3000203@mentor.com> References: <50A0FB68.5060100@mentor.com> <20121112142928.GB23655@Krystal> <50A36A7E.3000203@mentor.com> Message-ID: <20121114160737.GA32677@Krystal> * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > On 11/12/2012 03:29 PM, Mathieu Desnoyers wrote: > > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > >> The probes are verified to compile against all kernel versions from > >> 3.0 to 3.6 (3.7-rc5 also works). > > > > LTTng-modules states that 2.6.38 and 2.6.39 are supported too. Could you > > test those against these two kernel versions too ? > > Added support down to 2.6.38 (couple more ifdefs in net.h) > See Subject: [PATCH 2/3] Add ifdefs to net probe to support Linux 2.6.39 > > > > lttng-modules TP_fast_assign() section should not have semicolumn at the > > end of lines, e.g.: > > > > TP_fast_assign( > > tp_strcpy(name, codec->name) > > tp_assign(id, codec->id) > > tp_assign(reg, reg) > > tp_assign(val, val) > > ) > > Fixed for all probes. > See Subject: [PATCH 3/3] Remove semicolons in TP_fast_assign blocks. > > > And now the updated patch series ... All merged. For next time, a few nits: please send each patch in a separate email, and usually we don't put dots at the end of titles. Also, if you can put your Signed-off-by at the end of the patch header, it would follow our workflow entirely. Thanks! Mathieu > > From bb32fa6dd5e569d110b0f60ba705a398265a7617 Mon Sep 17 00:00:00 2001 > From: Paul Woegerer > Date: Mon, 12 Nov 2012 14:07:12 +0100 > Subject: [PATCH 1/3] Add kernel probes for asoc, ext3, gpio, jbd, jbd2, kmem, > lock, module, napi, net, power, regulator, scsi, skb, > sock, udp, vmscan. > > --- > instrumentation/events/lttng-module/asoc.h | 340 ++++++ > instrumentation/events/lttng-module/ext3.h | 870 +++++++++++++++ > instrumentation/events/lttng-module/gpio.h | 56 + > instrumentation/events/lttng-module/jbd.h | 243 +++++ > instrumentation/events/lttng-module/jbd2.h | 238 ++++ > instrumentation/events/lttng-module/kmem.h | 304 ++++++ > instrumentation/events/lttng-module/lock.h | 86 ++ > instrumentation/events/lttng-module/module.h | 134 +++ > instrumentation/events/lttng-module/napi.h | 38 + > instrumentation/events/lttng-module/net.h | 84 ++ > instrumentation/events/lttng-module/power.h | 240 ++++ > instrumentation/events/lttng-module/regulator.h | 141 +++ > instrumentation/events/lttng-module/scsi.h | 369 +++++++ > instrumentation/events/lttng-module/skb.h | 75 ++ > instrumentation/events/lttng-module/sock.h | 68 ++ > instrumentation/events/lttng-module/udp.h | 32 + > instrumentation/events/lttng-module/vmscan.h | 499 +++++++++ > instrumentation/events/mainline/asoc.h | 330 ++++++ > instrumentation/events/mainline/ext3.h | 864 +++++++++++++++ > instrumentation/events/mainline/fs_ext3.h | 1323 +++++++++++++++++++++++ > instrumentation/events/mainline/gpio.h | 56 + > instrumentation/events/mainline/jbd.h | 203 ++++ > instrumentation/events/mainline/jbd2.h | 235 ++++ > instrumentation/events/mainline/kmem.h | 308 ++++++ > instrumentation/events/mainline/lock.h | 86 ++ > instrumentation/events/mainline/module.h | 131 +++ > instrumentation/events/mainline/napi.h | 38 + > instrumentation/events/mainline/net.h | 84 ++ > instrumentation/events/mainline/power.h | 240 ++++ > instrumentation/events/mainline/regulator.h | 141 +++ > instrumentation/events/mainline/scsi.h | 365 +++++++ > instrumentation/events/mainline/skb.h | 75 ++ > instrumentation/events/mainline/sock.h | 68 ++ > instrumentation/events/mainline/udp.h | 32 + > instrumentation/events/mainline/vmscan.h | 477 ++++++++ > probes/Makefile | 72 ++ > probes/lttng-probe-asoc.c | 45 + > probes/lttng-probe-ext3.c | 56 + > probes/lttng-probe-gpio.c | 43 + > probes/lttng-probe-jbd.c | 44 + > probes/lttng-probe-jbd2.c | 43 + > probes/lttng-probe-kmem.c | 43 + > probes/lttng-probe-lock.c | 43 + > probes/lttng-probe-module.c | 43 + > probes/lttng-probe-napi.c | 43 + > probes/lttng-probe-net.c | 43 + > probes/lttng-probe-power.c | 43 + > probes/lttng-probe-regulator.c | 43 + > probes/lttng-probe-scsi.c | 44 + > probes/lttng-probe-skb.c | 43 + > probes/lttng-probe-sock.c | 43 + > probes/lttng-probe-udp.c | 43 + > probes/lttng-probe-vmscan.c | 48 + > 53 files changed, 9698 insertions(+) > create mode 100644 instrumentation/events/lttng-module/asoc.h > create mode 100644 instrumentation/events/lttng-module/ext3.h > create mode 100644 instrumentation/events/lttng-module/gpio.h > create mode 100644 instrumentation/events/lttng-module/jbd.h > create mode 100644 instrumentation/events/lttng-module/jbd2.h > create mode 100644 instrumentation/events/lttng-module/kmem.h > create mode 100644 instrumentation/events/lttng-module/lock.h > create mode 100644 instrumentation/events/lttng-module/module.h > create mode 100644 instrumentation/events/lttng-module/napi.h > create mode 100644 instrumentation/events/lttng-module/net.h > create mode 100644 instrumentation/events/lttng-module/power.h > create mode 100644 instrumentation/events/lttng-module/regulator.h > create mode 100644 instrumentation/events/lttng-module/scsi.h > create mode 100644 instrumentation/events/lttng-module/skb.h > create mode 100644 instrumentation/events/lttng-module/sock.h > create mode 100644 instrumentation/events/lttng-module/udp.h > create mode 100644 instrumentation/events/lttng-module/vmscan.h > create mode 100644 instrumentation/events/mainline/asoc.h > create mode 100644 instrumentation/events/mainline/ext3.h > create mode 100644 instrumentation/events/mainline/fs_ext3.h > create mode 100644 instrumentation/events/mainline/gpio.h > create mode 100644 instrumentation/events/mainline/jbd.h > create mode 100644 instrumentation/events/mainline/jbd2.h > create mode 100644 instrumentation/events/mainline/kmem.h > create mode 100644 instrumentation/events/mainline/lock.h > create mode 100644 instrumentation/events/mainline/module.h > create mode 100644 instrumentation/events/mainline/napi.h > create mode 100644 instrumentation/events/mainline/net.h > create mode 100644 instrumentation/events/mainline/power.h > create mode 100644 instrumentation/events/mainline/regulator.h > create mode 100644 instrumentation/events/mainline/scsi.h > create mode 100644 instrumentation/events/mainline/skb.h > create mode 100644 instrumentation/events/mainline/sock.h > create mode 100644 instrumentation/events/mainline/udp.h > create mode 100644 instrumentation/events/mainline/vmscan.h > create mode 100644 probes/lttng-probe-asoc.c > create mode 100644 probes/lttng-probe-ext3.c > create mode 100644 probes/lttng-probe-gpio.c > create mode 100644 probes/lttng-probe-jbd.c > create mode 100644 probes/lttng-probe-jbd2.c > create mode 100644 probes/lttng-probe-kmem.c > create mode 100644 probes/lttng-probe-lock.c > create mode 100644 probes/lttng-probe-module.c > create mode 100644 probes/lttng-probe-napi.c > create mode 100644 probes/lttng-probe-net.c > create mode 100644 probes/lttng-probe-power.c > create mode 100644 probes/lttng-probe-regulator.c > create mode 100644 probes/lttng-probe-scsi.c > create mode 100644 probes/lttng-probe-skb.c > create mode 100644 probes/lttng-probe-sock.c > create mode 100644 probes/lttng-probe-udp.c > create mode 100644 probes/lttng-probe-vmscan.c > > diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h > new file mode 100644 > index 0000000..cb9e701 > --- /dev/null > +++ b/instrumentation/events/lttng-module/asoc.h > @@ -0,0 +1,340 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM asoc > + > +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_ASOC_H > + > +#include > +#include > +#include > + > +#ifndef _TRACE_ASOC_DEF > +#define _TRACE_ASOC_DEF > +struct snd_soc_jack; > +struct snd_soc_codec; > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) > +struct snd_soc_platform; > +#endif > +struct snd_soc_card; > +struct snd_soc_dapm_widget; > +#endif > + > +/* > + * Log register events > + */ > +DECLARE_EVENT_CLASS(snd_soc_reg, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, codec->name); > + tp_assign(id, codec->id); > + tp_assign(reg, reg); > + tp_assign(val, val); > + ), > + > + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +) > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +) > + > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) > +DECLARE_EVENT_CLASS(snd_soc_preg, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val), > + > + TP_STRUCT__entry( > + __string( name, platform->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, platform->name); > + tp_assign(id, platform->id); > + tp_assign(reg, reg); > + tp_assign(val, val); > + ), > + > + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +) > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +) > +#endif > + > +DECLARE_EVENT_CLASS(snd_soc_card, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, card->name); > + tp_assign(val, val); > + ), > + > + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +) > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +) > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, card->name); > + ), > + > + TP_printk("card=%s", __get_str(name)) > +) > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +) > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +) > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val), > + > + TP_STRUCT__entry( > + __string( name, w->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, w->name); > + tp_assign(val, val); > + ), > + > + TP_printk("widget=%s val=%d", __get_str(name), > + (int)__entry->val) > +) > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +) > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +) > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +) > + > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) > +TRACE_EVENT(snd_soc_dapm_walk_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, power_checks ) > + __field( int, path_checks ) > + __field( int, neighbour_checks ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, card->name); > + tp_assign(power_checks, card->dapm_stats.power_checks); > + tp_assign(path_checks, card->dapm_stats.path_checks); > + tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks); > + ), > + > + TP_printk("%s: checks %d power, %d path, %d neighbour", > + __get_str(name), (int)__entry->power_checks, > + (int)__entry->path_checks, (int)__entry->neighbour_checks) > +) > +#endif > + > +TRACE_EVENT(snd_soc_jack_irq, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + ), > + > + TP_printk("%s", __get_str(name)) > +) > + > +TRACE_EVENT(snd_soc_jack_report, > + > + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), > + > + TP_ARGS(jack, mask, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, mask ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, jack->jack->name); > + tp_assign(mask, mask); > + tp_assign(val, val); > + ), > + > + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, > + (int)__entry->mask) > +) > + > +TRACE_EVENT(snd_soc_jack_notify, > + > + TP_PROTO(struct snd_soc_jack *jack, int val), > + > + TP_ARGS(jack, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, jack->jack->name); > + tp_assign(val, val); > + ), > + > + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) > +) > + > +TRACE_EVENT(snd_soc_cache_sync, > + > + TP_PROTO(struct snd_soc_codec *codec, const char *type, > + const char *status), > + > + TP_ARGS(codec, type, status), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __string( status, status ) > + __string( type, type ) > + __field( int, id ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, codec->name); > + tp_strcpy(status, status); > + tp_strcpy(type, type); > + tp_assign(id, codec->id); > + ), > + > + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), > + (int)__entry->id, __get_str(type), __get_str(status)) > +) > + > +#endif /* _TRACE_ASOC_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h > new file mode 100644 > index 0000000..e02ecf4 > --- /dev/null > +++ b/instrumentation/events/lttng-module/ext3.h > @@ -0,0 +1,870 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM ext3 > + > +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_EXT3_H > + > +#include > + > +#ifndef _TRACE_EXT3_DEF > +#define _TRACE_EXT3_DEF > +static struct dentry *dentry; > +#endif > + > + > +TRACE_EVENT(ext3_free_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( uid_t, uid ) > + __field( gid_t, gid ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(mode, inode->i_mode); > + tp_assign(uid, inode->i_uid); > + tp_assign(gid, inode->i_gid); > + tp_assign(blocks, inode->i_blocks); > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->uid, __entry->gid, > + (unsigned long) __entry->blocks) > +) > + > +TRACE_EVENT(ext3_request_inode, > + TP_PROTO(struct inode *dir, int mode), > + > + TP_ARGS(dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, dir->i_sb->s_dev); > + tp_assign(dir, dir->i_ino); > + tp_assign(mode, mode); > + ), > + > + TP_printk("dev %d,%d dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->dir, __entry->mode) > +) > + > +TRACE_EVENT(ext3_allocate_inode, > + TP_PROTO(struct inode *inode, struct inode *dir, int mode), > + > + TP_ARGS(inode, dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(dir, dir->i_ino); > + tp_assign(mode, mode); > + ), > + > + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->dir, __entry->mode) > +) > + > +TRACE_EVENT(ext3_evict_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, nlink ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(nlink, inode->i_nlink); > + ), > + > + TP_printk("dev %d,%d ino %lu nlink %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->nlink) > +) > + > +TRACE_EVENT(ext3_drop_inode, > + TP_PROTO(struct inode *inode, int drop), > + > + TP_ARGS(inode, drop), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, drop ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(drop, drop); > + ), > + > + TP_printk("dev %d,%d ino %lu drop %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->drop) > +) > + > +TRACE_EVENT(ext3_mark_inode_dirty, > + TP_PROTO(struct inode *inode, unsigned long IP), > + > + TP_ARGS(inode, IP), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field(unsigned long, ip ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(ip, IP); > + ), > + > + TP_printk("dev %d,%d ino %lu caller %pF", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (void *)__entry->ip) > +) > + > +TRACE_EVENT(ext3_write_begin, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int flags), > + > + TP_ARGS(inode, pos, len, flags), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, flags ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(pos, pos); > + tp_assign(len, len); > + tp_assign(flags, flags); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->flags) > +) > + > +DECLARE_EVENT_CLASS(ext3__write_end, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, copied ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(pos, pos); > + tp_assign(len, len); > + tp_assign(copied, copied); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->copied) > +) > + > +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +) > + > +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +) > + > +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +) > + > +DECLARE_EVENT_CLASS(ext3__page_op, > + TP_PROTO(struct page *page), > + > + TP_ARGS(page), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( pgoff_t, index ) > + > + ), > + > + TP_fast_assign( > + tp_assign(index, page->index); > + tp_assign(ino, page->mapping->host->i_ino); > + tp_assign(dev, page->mapping->host->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->index) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_readpage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +DEFINE_EVENT(ext3__page_op, ext3_releasepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +) > + > +TRACE_EVENT(ext3_invalidatepage, > + TP_PROTO(struct page *page, unsigned long offset), > + > + TP_ARGS(page, offset), > + > + TP_STRUCT__entry( > + __field( pgoff_t, index ) > + __field( unsigned long, offset ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + > + ), > + > + TP_fast_assign( > + tp_assign(index, page->index); > + tp_assign(offset, offset); > + tp_assign(ino, page->mapping->host->i_ino); > + tp_assign(dev, page->mapping->host->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->index, __entry->offset) > +) > + > +TRACE_EVENT(ext3_discard_blocks, > + TP_PROTO(struct super_block *sb, unsigned long blk, > + unsigned long count), > + > + TP_ARGS(sb, blk, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, blk ) > + __field( unsigned long, count ) > + > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(blk, blk); > + tp_assign(count, count); > + ), > + > + TP_printk("dev %d,%d blk %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->blk, __entry->count) > +) > + > +TRACE_EVENT(ext3_request_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count), > + > + TP_ARGS(inode, goal, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(count, count); > + tp_assign(goal, goal); > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->goal) > +) > + > +TRACE_EVENT(ext3_allocate_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count, unsigned long block), > + > + TP_ARGS(inode, goal, count, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(block, block); > + tp_assign(count, count); > + tp_assign(goal, goal); > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->block, > + __entry->goal) > +) > + > +TRACE_EVENT(ext3_free_blocks, > + TP_PROTO(struct inode *inode, unsigned long block, > + unsigned long count), > + > + TP_ARGS(inode, block, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(mode, inode->i_mode); > + tp_assign(block, block); > + tp_assign(count, count); > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->block, __entry->count) > +) > + > +TRACE_EVENT(ext3_sync_file_enter, > + TP_PROTO(struct file *file, int datasync), > + > + TP_ARGS(file, datasync), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, parent ) > + __field( int, datasync ) > + ), > + > + TP_fast_assign( > + dentry = file->f_path.dentry; > + > + tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + tp_assign(ino, dentry->d_inode->i_ino); > + tp_assign(datasync, datasync); > + tp_assign(parent, dentry->d_parent->d_inode->i_ino); > + ), > + > + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->parent, __entry->datasync) > +) > + > +TRACE_EVENT(ext3_sync_file_exit, > + TP_PROTO(struct inode *inode, int ret), > + > + TP_ARGS(inode, ret), > + > + TP_STRUCT__entry( > + __field( int, ret ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(ret, ret); > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +) > + > +TRACE_EVENT(ext3_sync_fs, > + TP_PROTO(struct super_block *sb, int wait), > + > + TP_ARGS(sb, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(wait, wait); > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +) > + > +TRACE_EVENT(ext3_rsv_window_add, > + TP_PROTO(struct super_block *sb, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(start, rsv_node->rsv_window._rsv_start); > + tp_assign(end, rsv_node->rsv_window._rsv_end); > + ), > + > + TP_printk("dev %d,%d start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->start, __entry->end) > +) > + > +TRACE_EVENT(ext3_discard_reservation, > + TP_PROTO(struct inode *inode, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(inode, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(start, rsv_node->rsv_window._rsv_start); > + tp_assign(end, rsv_node->rsv_window._rsv_end); > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long)__entry->ino, __entry->start, > + __entry->end) > +) > + > +TRACE_EVENT(ext3_alloc_new_reservation, > + TP_PROTO(struct super_block *sb, unsigned long goal), > + > + TP_ARGS(sb, goal), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(goal, goal); > + ), > + > + TP_printk("dev %d,%d goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->goal) > +) > + > +TRACE_EVENT(ext3_reserved, > + TP_PROTO(struct super_block *sb, unsigned long block, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, block, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, block ) > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(block, block); > + tp_assign(start, rsv_node->rsv_window._rsv_start); > + tp_assign(end, rsv_node->rsv_window._rsv_end); > + tp_assign(dev, sb->s_dev); > + ), > + > + TP_printk("dev %d,%d block %lu, start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->block, __entry->start, __entry->end) > +) > + > +TRACE_EVENT(ext3_forget, > + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), > + > + TP_ARGS(inode, is_metadata, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( int, is_metadata ) > + __field( unsigned long, block ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + tp_assign(mode, inode->i_mode); > + tp_assign(is_metadata, is_metadata); > + tp_assign(block, block); > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->is_metadata, __entry->block) > +) > + > +TRACE_EVENT(ext3_read_block_bitmap, > + TP_PROTO(struct super_block *sb, unsigned int group), > + > + TP_ARGS(sb, group), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( __u32, group ) > + > + ), > + > + TP_fast_assign( > + tp_assign(dev, sb->s_dev); > + tp_assign(group, group); > + ), > + > + TP_printk("dev %d,%d group %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->group) > +) > + > +TRACE_EVENT(ext3_direct_IO_enter, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), > + > + TP_ARGS(inode, offset, len, rw), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(pos, offset); > + tp_assign(len, len); > + tp_assign(rw, rw); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw) > +) > + > +TRACE_EVENT(ext3_direct_IO_exit, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, > + int rw, int ret), > + > + TP_ARGS(inode, offset, len, rw, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(pos, offset); > + tp_assign(len, len); > + tp_assign(rw, rw); > + tp_assign(ret, ret); > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw, __entry->ret) > +) > + > +TRACE_EVENT(ext3_unlink_enter, > + TP_PROTO(struct inode *parent, struct dentry *dentry), > + > + TP_ARGS(parent, dentry), > + > + TP_STRUCT__entry( > + __field( ino_t, parent ) > + __field( ino_t, ino ) > + __field( loff_t, size ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(parent, parent->i_ino); > + tp_assign(ino, dentry->d_inode->i_ino); > + tp_assign(size, dentry->d_inode->i_size); > + tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu size %lld parent %ld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long)__entry->size, > + (unsigned long) __entry->parent) > +) > + > +TRACE_EVENT(ext3_unlink_exit, > + TP_PROTO(struct dentry *dentry, int ret), > + > + TP_ARGS(dentry, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, dentry->d_inode->i_ino); > + tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + tp_assign(ret, ret); > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +) > + > +DECLARE_EVENT_CLASS(ext3__truncate, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(blocks, inode->i_blocks); > + ), > + > + TP_printk("dev %d,%d ino %lu blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) > +) > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +) > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +) > + > +TRACE_EVENT(ext3_get_blocks_enter, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long len, int create), > + > + TP_ARGS(inode, lblk, len, create), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, len ) > + __field( int, create ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(lblk, lblk); > + tp_assign(len, len); > + tp_assign(create, create); > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->len, __entry->create) > +) > + > +TRACE_EVENT(ext3_get_blocks_exit, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long pblk, unsigned long len, int ret), > + > + TP_ARGS(inode, lblk, pblk, len, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, pblk ) > + __field( unsigned long, len ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(lblk, lblk); > + tp_assign(pblk, pblk); > + tp_assign(len, len); > + tp_assign(ret, ret); > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->pblk, > + __entry->len, __entry->ret) > +) > + > +TRACE_EVENT(ext3_load_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev); > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +) > + > +#endif /* _TRACE_EXT3_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/gpio.h b/instrumentation/events/lttng-module/gpio.h > new file mode 100644 > index 0000000..e6002c4 > --- /dev/null > +++ b/instrumentation/events/lttng-module/gpio.h > @@ -0,0 +1,56 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM gpio > + > +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_GPIO_H > + > +#include > + > +TRACE_EVENT(gpio_direction, > + > + TP_PROTO(unsigned gpio, int in, int err), > + > + TP_ARGS(gpio, in, err), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, in) > + __field(int, err) > + ), > + > + TP_fast_assign( > + tp_assign(gpio, gpio); > + tp_assign(in, in); > + tp_assign(err, err); > + ), > + > + TP_printk("%u %3s (%d)", __entry->gpio, > + __entry->in ? "in" : "out", __entry->err) > +) > + > +TRACE_EVENT(gpio_value, > + > + TP_PROTO(unsigned gpio, int get, int value), > + > + TP_ARGS(gpio, get, value), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, get) > + __field(int, value) > + ), > + > + TP_fast_assign( > + tp_assign(gpio, gpio); > + tp_assign(get, get); > + tp_assign(value, value); > + ), > + > + TP_printk("%u %3s %d", __entry->gpio, > + __entry->get ? "get" : "set", __entry->value) > +) > + > +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h > new file mode 100644 > index 0000000..97ba1e5 > --- /dev/null > +++ b/instrumentation/events/lttng-module/jbd.h > @@ -0,0 +1,243 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd > + > +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD_H > + > +#include > +#include > + > +TRACE_EVENT(jbd_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(result, result); > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->result) > +) > + > +DECLARE_EVENT_CLASS(jbd_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +#else > + TP_printk("dev %d,%d transaction %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction) > +#endif > +) > + > +DEFINE_EVENT(jbd_commit, jbd_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd_commit, jbd_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd_commit, jbd_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +TRACE_EVENT(jbd_drop_transaction, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +#else > + TP_printk("dev %d,%d transaction %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction) > +#endif > +) > + > +TRACE_EVENT(jbd_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(head, journal->j_tail_sequence); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +#else > + TP_printk("dev %d,%d transaction %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->head) > +#endif > +) > + > +TRACE_EVENT(jbd_do_submit_data, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + __field( char, sync_commit ) > +#endif > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > +#endif > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +#else > + TP_printk("dev %d,%d transaction %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction) > +#endif > +) > + > +TRACE_EVENT(jbd_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(tail_sequence, journal->j_tail_sequence); > + tp_assign(first_tid, first_tid); > + tp_assign(block_nr, block_nr); > + tp_assign(freed, freed); > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +) > + > +TRACE_EVENT(jbd_update_superblock_end, > + TP_PROTO(journal_t *journal, int wait), > + > + TP_ARGS(journal, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(wait, wait); > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +) > + > +#endif /* _TRACE_JBD_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h > new file mode 100644 > index 0000000..2e80832 > --- /dev/null > +++ b/instrumentation/events/lttng-module/jbd2.h > @@ -0,0 +1,238 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd2 > + > +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD2_H > + > +#include > +#include > + > +#ifndef _TRACE_JBD2_DEF > +#define _TRACE_JBD2_DEF > +struct transaction_chp_stats_s; > +struct transaction_run_stats_s; > +#endif > + > +TRACE_EVENT(jbd2_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(result, result); > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) > +) > + > +DECLARE_EVENT_CLASS(jbd2_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(transaction, commit_transaction->t_tid); > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > + > +TRACE_EVENT(jbd2_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(head, journal->j_tail_sequence); > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +) > + > +TRACE_EVENT(jbd2_submit_inode_data, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino); > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +) > + > +TRACE_EVENT(jbd2_run_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_run_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, wait ) > + __field( unsigned long, running ) > + __field( unsigned long, locked ) > + __field( unsigned long, flushing ) > + __field( unsigned long, logging ) > + __field( __u32, handle_count ) > + __field( __u32, blocks ) > + __field( __u32, blocks_logged ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, dev); > + tp_assign(tid, tid); > + tp_assign(wait, stats->rs_wait); > + tp_assign(running, stats->rs_running); > + tp_assign(locked, stats->rs_locked); > + tp_assign(flushing, stats->rs_flushing); > + tp_assign(logging, stats->rs_logging); > + tp_assign(handle_count, stats->rs_handle_count); > + tp_assign(blocks, stats->rs_blocks); > + tp_assign(blocks_logged, stats->rs_blocks_logged); > + ), > + > + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " > + "logging %u handle_count %u blocks %u blocks_logged %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->wait), > + jiffies_to_msecs(__entry->running), > + jiffies_to_msecs(__entry->locked), > + jiffies_to_msecs(__entry->flushing), > + jiffies_to_msecs(__entry->logging), > + __entry->handle_count, __entry->blocks, > + __entry->blocks_logged) > +) > + > +TRACE_EVENT(jbd2_checkpoint_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_chp_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, chp_time ) > + __field( __u32, forced_to_close ) > + __field( __u32, written ) > + __field( __u32, dropped ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, dev); > + tp_assign(tid, tid); > + tp_assign(chp_time, stats->cs_chp_time); > + tp_assign(forced_to_close, stats->cs_forced_to_close); > + tp_assign(written, stats->cs_written); > + tp_assign(dropped, stats->cs_dropped); > + ), > + > + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " > + "written %u dropped %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->chp_time), > + __entry->forced_to_close, __entry->written, __entry->dropped) > +) > + > +TRACE_EVENT(jbd2_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(tail_sequence, journal->j_tail_sequence); > + tp_assign(first_tid, first_tid); > + tp_assign(block_nr, block_nr); > + tp_assign(freed, freed); > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +) > + > +#endif /* _TRACE_JBD2_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h > new file mode 100644 > index 0000000..04f668b > --- /dev/null > +++ b/instrumentation/events/lttng-module/kmem.h > @@ -0,0 +1,304 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM kmem > + > +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_KMEM_H > + > +DECLARE_EVENT_CLASS(kmem_alloc, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + tp_assign(call_site, call_site); > + tp_assign(ptr, ptr); > + tp_assign(bytes_req, bytes_req); > + tp_assign(bytes_alloc, bytes_alloc); > + tp_assign(gfp_flags, gfp_flags); > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags)) > +) > + > +DEFINE_EVENT(kmem_alloc, kmalloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +) > + > +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +) > + > +DECLARE_EVENT_CLASS(kmem_alloc_node, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags, > + int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + __field( int, node ) > + ), > + > + TP_fast_assign( > + tp_assign(call_site, call_site); > + tp_assign(ptr, ptr); > + tp_assign(bytes_req, bytes_req); > + tp_assign(bytes_alloc, bytes_alloc); > + tp_assign(gfp_flags, gfp_flags); > + tp_assign(node, node); > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags), > + __entry->node) > +) > + > +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +) > + > +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +) > + > +DECLARE_EVENT_CLASS(kmem_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + ), > + > + TP_fast_assign( > + tp_assign(call_site, call_site); > + tp_assign(ptr, ptr); > + ), > + > + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > +) > + > +DEFINE_EVENT(kmem_free, kfree, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +) > + > +DEFINE_EVENT(kmem_free, kmem_cache_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +) > + > +TRACE_EVENT(mm_page_free_direct, > + > + TP_PROTO(struct page *page, unsigned int order), > + > + TP_ARGS(page, order), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(order, order); > + ), > + > + TP_printk("page=%p pfn=%lu order=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order) > +) > + > +TRACE_EVENT(mm_pagevec_free, > + > + TP_PROTO(struct page *page, int cold), > + > + TP_ARGS(page, cold), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, cold ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(cold, cold); > + ), > + > + TP_printk("page=%p pfn=%lu order=0 cold=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->cold) > +) > + > +TRACE_EVENT(mm_page_alloc, > + > + TP_PROTO(struct page *page, unsigned int order, > + gfp_t gfp_flags, int migratetype), > + > + TP_ARGS(page, order, gfp_flags, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( gfp_t, gfp_flags ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(order, order); > + tp_assign(gfp_flags, gfp_flags); > + tp_assign(migratetype, migratetype); > + ), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + show_gfp_flags(__entry->gfp_flags)) > +) > + > +DECLARE_EVENT_CLASS(mm_page, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(order, order); > + tp_assign(migratetype, migratetype); > + ), > + > + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + __entry->order == 0) > +) > + > +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype) > +) > + > +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", > + __entry->page, page_to_pfn(__entry->page), > + __entry->order, __entry->migratetype) > +) > + > +TRACE_EVENT(mm_page_alloc_extfrag, > + > + TP_PROTO(struct page *page, > + int alloc_order, int fallback_order, > + int alloc_migratetype, int fallback_migratetype), > + > + TP_ARGS(page, > + alloc_order, fallback_order, > + alloc_migratetype, fallback_migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, alloc_order ) > + __field( int, fallback_order ) > + __field( int, alloc_migratetype ) > + __field( int, fallback_migratetype ) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(alloc_order, alloc_order); > + tp_assign(fallback_order, fallback_order); > + tp_assign(alloc_migratetype, alloc_migratetype); > + tp_assign(fallback_migratetype, fallback_migratetype); > + ), > + > + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->alloc_order, > + __entry->fallback_order, > + pageblock_order, > + __entry->alloc_migratetype, > + __entry->fallback_migratetype, > + __entry->fallback_order < pageblock_order, > + __entry->alloc_migratetype == __entry->fallback_migratetype) > +) > + > +#endif /* _TRACE_KMEM_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/lock.h b/instrumentation/events/lttng-module/lock.h > new file mode 100644 > index 0000000..75101f6 > --- /dev/null > +++ b/instrumentation/events/lttng-module/lock.h > @@ -0,0 +1,86 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM lock > + > +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_LOCK_H > + > +#include > +#include > + > +#ifdef CONFIG_LOCKDEP > + > +TRACE_EVENT(lock_acquire, > + > + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, > + int trylock, int read, int check, > + struct lockdep_map *next_lock, unsigned long ip), > + > + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), > + > + TP_STRUCT__entry( > + __field(unsigned int, flags) > + __string(name, lock->name) > + __field(void *, lockdep_addr) > + ), > + > + TP_fast_assign( > + tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)); > + tp_strcpy(name, lock->name); > + tp_assign(lockdep_addr, lock); > + ), > + > + TP_printk("%p %s%s%s", __entry->lockdep_addr, > + (__entry->flags & 1) ? "try " : "", > + (__entry->flags & 2) ? "read " : "", > + __get_str(name)) > +) > + > +DECLARE_EVENT_CLASS(lock, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip), > + > + TP_STRUCT__entry( > + __string( name, lock->name ) > + __field( void *, lockdep_addr ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, lock->name); > + tp_assign(lockdep_addr, lock); > + ), > + > + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) > +) > + > +DEFINE_EVENT(lock, lock_release, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +) > + > +#ifdef CONFIG_LOCK_STAT > + > +DEFINE_EVENT(lock, lock_contended, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +) > + > +DEFINE_EVENT(lock, lock_acquired, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +) > + > +#endif > +#endif > + > +#endif /* _TRACE_LOCK_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/module.h b/instrumentation/events/lttng-module/module.h > new file mode 100644 > index 0000000..2e83431 > --- /dev/null > +++ b/instrumentation/events/lttng-module/module.h > @@ -0,0 +1,134 @@ > +/* > + * Because linux/module.h has tracepoints in the header, and ftrace.h > + * eventually includes this file, define_trace.h includes linux/module.h > + * But we do not want the module.h to override the TRACE_SYSTEM macro > + * variable that define_trace.h is processing, so we only set it > + * when module events are being processed, which would happen when > + * CREATE_TRACE_POINTS is defined. > + */ > +#ifdef CREATE_TRACE_POINTS > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM module > +#endif > + > +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_MODULE_H > + > +#include > + > +#ifdef CONFIG_MODULES > + > +#ifndef _TRACE_MODULE_DEF > +#define _TRACE_MODULE_DEF > +struct module; > + > +#define show_module_flags(flags) __print_flags(flags, "", \ > + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ > + { (1UL << TAINT_FORCED_MODULE), "F" }, \ > + { (1UL << TAINT_CRAP), "C" }) > +#endif > + > +TRACE_EVENT(module_load, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __field( unsigned int, taints ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + tp_assign(taints, mod->taints); > + tp_strcpy(name, mod->name); > + ), > + > + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) > +) > + > +TRACE_EVENT(module_free, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, mod->name); > + ), > + > + TP_printk("%s", __get_str(name)) > +) > + > +#ifdef CONFIG_MODULE_UNLOAD > +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ > + > +DECLARE_EVENT_CLASS(module_refcnt, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( int, refcnt ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + tp_assign(ip, ip); > + tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)); > + tp_strcpy(name, mod->name); > + ), > + > + TP_printk("%s call_site=%pf refcnt=%d", > + __get_str(name), (void *)__entry->ip, __entry->refcnt) > +) > + > +DEFINE_EVENT(module_refcnt, module_get, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +) > + > +DEFINE_EVENT(module_refcnt, module_put, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +) > +#endif /* CONFIG_MODULE_UNLOAD */ > + > +TRACE_EVENT(module_request, > + > + TP_PROTO(char *name, bool wait, unsigned long ip), > + > + TP_ARGS(name, wait, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( bool, wait ) > + __string( name, name ) > + ), > + > + TP_fast_assign( > + tp_assign(ip, ip); > + tp_assign(wait, wait); > + tp_strcpy(name, name); > + ), > + > + TP_printk("%s wait=%d call_site=%pf", > + __get_str(name), (int)__entry->wait, (void *)__entry->ip) > +) > + > +#endif /* CONFIG_MODULES */ > + > +#endif /* _TRACE_MODULE_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/napi.h b/instrumentation/events/lttng-module/napi.h > new file mode 100644 > index 0000000..58b8336 > --- /dev/null > +++ b/instrumentation/events/lttng-module/napi.h > @@ -0,0 +1,38 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM napi > + > +#if !defined(_TRACE_NAPI_H_) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NAPI_H_ > + > +#include > +#include > +#include > + > +#define NO_DEV "(no_device)" > + > +TRACE_EVENT(napi_poll, > + > + TP_PROTO(struct napi_struct *napi), > + > + TP_ARGS(napi), > + > + TP_STRUCT__entry( > + __field( struct napi_struct *, napi) > + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) > + ), > + > + TP_fast_assign( > + tp_assign(napi, napi); > + tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV); > + ), > + > + TP_printk("napi poll on napi struct %p for device %s", > + __entry->napi, __get_str(dev_name)) > +) > + > +#undef NO_DEV > + > +#endif /* _TRACE_NAPI_H_ */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h > new file mode 100644 > index 0000000..c25b0d9 > --- /dev/null > +++ b/instrumentation/events/lttng-module/net.h > @@ -0,0 +1,84 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM net > + > +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NET_H > + > +#include > +#include > +#include > +#include > + > +TRACE_EVENT(net_dev_xmit, > + > + TP_PROTO(struct sk_buff *skb, > + int rc, > + struct net_device *dev, > + unsigned int skb_len), > + > + TP_ARGS(skb, rc, dev, skb_len), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __field( int, rc ) > + __string( name, dev->name ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, skb_len); > + tp_assign(rc, rc); > + tp_strcpy(name, dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", > + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) > +) > + > +DECLARE_EVENT_CLASS(net_dev_template, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __string( name, skb->dev->name ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, skb->len); > + tp_strcpy(name, skb->dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u", > + __get_str(name), __entry->skbaddr, __entry->len) > +) > + > +DEFINE_EVENT(net_dev_template, net_dev_queue, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +) > + > +DEFINE_EVENT(net_dev_template, netif_receive_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +) > + > +DEFINE_EVENT(net_dev_template, netif_rx, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +) > +#endif /* _TRACE_NET_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h > new file mode 100644 > index 0000000..05aced7 > --- /dev/null > +++ b/instrumentation/events/lttng-module/power.h > @@ -0,0 +1,240 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM power > + > +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_POWER_H > + > +#include > +#include > + > +DECLARE_EVENT_CLASS(cpu, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + __field( u32, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, > + (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(cpu, cpu_idle, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id) > +) > + > +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING > + > +#define PWR_EVENT_EXIT -1 > +#endif > + > +DEFINE_EVENT(cpu, cpu_frequency, > + > + TP_PROTO(unsigned int frequency, unsigned int cpu_id), > + > + TP_ARGS(frequency, cpu_id) > +) > + > +TRACE_EVENT(machine_suspend, > + > + TP_PROTO(unsigned int state), > + > + TP_ARGS(state), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + ), > + > + TP_fast_assign( > + tp_assign(state, state); > + ), > + > + TP_printk("state=%lu", (unsigned long)__entry->state) > +) > + > +/* This code will be removed after deprecation time exceeded (2.6.41) */ > +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED > + > +/* > + * The power events are used for cpuidle & suspend (power_start, power_end) > + * and for cpufreq (power_frequency) > + */ > +DECLARE_EVENT_CLASS(power, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, type ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_assign(type, type); > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(power, power_start, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +) > + > +DEFINE_EVENT(power, power_frequency, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +) > + > +TRACE_EVENT(power_end, > + > + TP_PROTO(unsigned int cpu_id), > + > + TP_ARGS(cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) > + > +) > + > +/* Deprecated dummy functions must be protected against multi-declartion */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > + > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > + > +/* These dummy declaration have to be ripped out when the deprecated > + events get removed */ > +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; > +static inline void trace_power_end(u64 cpuid) {}; > +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +/* > + * The clock events are used for clock enable/disable and for > + * clock rate change > + */ > +DECLARE_EVENT_CLASS(clock, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > + ), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(clock, clock_enable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > + > +DEFINE_EVENT(clock, clock_disable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > + > +DEFINE_EVENT(clock, clock_set_rate, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > + > +/* > + * The power domain events are used for power domains transitions > + */ > +DECLARE_EVENT_CLASS(power_domain, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(state, state); > + tp_assign(cpu_id, cpu_id); > +), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +) > + > +DEFINE_EVENT(power_domain, power_domain_target, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +) > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/regulator.h b/instrumentation/events/lttng-module/regulator.h > new file mode 100644 > index 0000000..e94da7c > --- /dev/null > +++ b/instrumentation/events/lttng-module/regulator.h > @@ -0,0 +1,141 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM regulator > + > +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_REGULATOR_H > + > +#include > +#include > + > +/* > + * Events which just log themselves and the regulator name for enable/disable > + * type tracking. > + */ > +DECLARE_EVENT_CLASS(regulator_basic, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + ), > + > + TP_printk("name=%s", __get_str(name)) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_enable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_enable_delay, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_enable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_disable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +DEFINE_EVENT(regulator_basic, regulator_disable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +) > + > +/* > + * Events that take a range of numerical values, mostly for voltages > + * and so on. > + */ > +DECLARE_EVENT_CLASS(regulator_range, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( int, min ) > + __field( int, max ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(min, min); > + tp_assign(max, max); > + ), > + > + TP_printk("name=%s (%d-%d)", __get_str(name), > + (int)__entry->min, (int)__entry->max) > +) > + > +DEFINE_EVENT(regulator_range, regulator_set_voltage, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max) > + > +) > + > + > +/* > + * Events that take a single value, mostly for readback and refcounts. > + */ > +DECLARE_EVENT_CLASS(regulator_value, > + > + TP_PROTO(const char *name, unsigned int val), > + > + TP_ARGS(name, val), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name); > + tp_assign(val, val); > + ), > + > + TP_printk("name=%s, val=%u", __get_str(name), > + (int)__entry->val) > +) > + > +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, > + > + TP_PROTO(const char *name, unsigned int value), > + > + TP_ARGS(name, value) > + > +) > + > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h > new file mode 100644 > index 0000000..27362f8 > --- /dev/null > +++ b/instrumentation/events/lttng-module/scsi.h > @@ -0,0 +1,369 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM scsi > + > +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SCSI_H > + > +#include > +#include > +#include > +#include > + > +#ifndef _TRACE_SCSI_DEF > +#define _TRACE_SCSI_DEF > + > +#define scsi_opcode_name(opcode) { opcode, #opcode } > +#define show_opcode_name(val) \ > + __print_symbolic(val, \ > + scsi_opcode_name(TEST_UNIT_READY), \ > + scsi_opcode_name(REZERO_UNIT), \ > + scsi_opcode_name(REQUEST_SENSE), \ > + scsi_opcode_name(FORMAT_UNIT), \ > + scsi_opcode_name(READ_BLOCK_LIMITS), \ > + scsi_opcode_name(REASSIGN_BLOCKS), \ > + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ > + scsi_opcode_name(READ_6), \ > + scsi_opcode_name(WRITE_6), \ > + scsi_opcode_name(SEEK_6), \ > + scsi_opcode_name(READ_REVERSE), \ > + scsi_opcode_name(WRITE_FILEMARKS), \ > + scsi_opcode_name(SPACE), \ > + scsi_opcode_name(INQUIRY), \ > + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ > + scsi_opcode_name(MODE_SELECT), \ > + scsi_opcode_name(RESERVE), \ > + scsi_opcode_name(RELEASE), \ > + scsi_opcode_name(COPY), \ > + scsi_opcode_name(ERASE), \ > + scsi_opcode_name(MODE_SENSE), \ > + scsi_opcode_name(START_STOP), \ > + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ > + scsi_opcode_name(SEND_DIAGNOSTIC), \ > + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ > + scsi_opcode_name(SET_WINDOW), \ > + scsi_opcode_name(READ_CAPACITY), \ > + scsi_opcode_name(READ_10), \ > + scsi_opcode_name(WRITE_10), \ > + scsi_opcode_name(SEEK_10), \ > + scsi_opcode_name(POSITION_TO_ELEMENT), \ > + scsi_opcode_name(WRITE_VERIFY), \ > + scsi_opcode_name(VERIFY), \ > + scsi_opcode_name(SEARCH_HIGH), \ > + scsi_opcode_name(SEARCH_EQUAL), \ > + scsi_opcode_name(SEARCH_LOW), \ > + scsi_opcode_name(SET_LIMITS), \ > + scsi_opcode_name(PRE_FETCH), \ > + scsi_opcode_name(READ_POSITION), \ > + scsi_opcode_name(SYNCHRONIZE_CACHE), \ > + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ > + scsi_opcode_name(READ_DEFECT_DATA), \ > + scsi_opcode_name(MEDIUM_SCAN), \ > + scsi_opcode_name(COMPARE), \ > + scsi_opcode_name(COPY_VERIFY), \ > + scsi_opcode_name(WRITE_BUFFER), \ > + scsi_opcode_name(READ_BUFFER), \ > + scsi_opcode_name(UPDATE_BLOCK), \ > + scsi_opcode_name(READ_LONG), \ > + scsi_opcode_name(WRITE_LONG), \ > + scsi_opcode_name(CHANGE_DEFINITION), \ > + scsi_opcode_name(WRITE_SAME), \ > + scsi_opcode_name(UNMAP), \ > + scsi_opcode_name(READ_TOC), \ > + scsi_opcode_name(LOG_SELECT), \ > + scsi_opcode_name(LOG_SENSE), \ > + scsi_opcode_name(XDWRITEREAD_10), \ > + scsi_opcode_name(MODE_SELECT_10), \ > + scsi_opcode_name(RESERVE_10), \ > + scsi_opcode_name(RELEASE_10), \ > + scsi_opcode_name(MODE_SENSE_10), \ > + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ > + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ > + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ > + scsi_opcode_name(REPORT_LUNS), \ > + scsi_opcode_name(MAINTENANCE_IN), \ > + scsi_opcode_name(MAINTENANCE_OUT), \ > + scsi_opcode_name(MOVE_MEDIUM), \ > + scsi_opcode_name(EXCHANGE_MEDIUM), \ > + scsi_opcode_name(READ_12), \ > + scsi_opcode_name(WRITE_12), \ > + scsi_opcode_name(WRITE_VERIFY_12), \ > + scsi_opcode_name(SEARCH_HIGH_12), \ > + scsi_opcode_name(SEARCH_EQUAL_12), \ > + scsi_opcode_name(SEARCH_LOW_12), \ > + scsi_opcode_name(READ_ELEMENT_STATUS), \ > + scsi_opcode_name(SEND_VOLUME_TAG), \ > + scsi_opcode_name(WRITE_LONG_2), \ > + scsi_opcode_name(READ_16), \ > + scsi_opcode_name(WRITE_16), \ > + scsi_opcode_name(VERIFY_16), \ > + scsi_opcode_name(WRITE_SAME_16), \ > + scsi_opcode_name(SERVICE_ACTION_IN), \ > + scsi_opcode_name(SAI_READ_CAPACITY_16), \ > + scsi_opcode_name(SAI_GET_LBA_STATUS), \ > + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ > + scsi_opcode_name(MO_SET_TARGET_PGS), \ > + scsi_opcode_name(READ_32), \ > + scsi_opcode_name(WRITE_32), \ > + scsi_opcode_name(WRITE_SAME_32), \ > + scsi_opcode_name(ATA_16), \ > + scsi_opcode_name(ATA_12)) > + > +#define scsi_hostbyte_name(result) { result, #result } > +#define show_hostbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_hostbyte_name(DID_OK), \ > + scsi_hostbyte_name(DID_NO_CONNECT), \ > + scsi_hostbyte_name(DID_BUS_BUSY), \ > + scsi_hostbyte_name(DID_TIME_OUT), \ > + scsi_hostbyte_name(DID_BAD_TARGET), \ > + scsi_hostbyte_name(DID_ABORT), \ > + scsi_hostbyte_name(DID_PARITY), \ > + scsi_hostbyte_name(DID_ERROR), \ > + scsi_hostbyte_name(DID_RESET), \ > + scsi_hostbyte_name(DID_BAD_INTR), \ > + scsi_hostbyte_name(DID_PASSTHROUGH), \ > + scsi_hostbyte_name(DID_SOFT_ERROR), \ > + scsi_hostbyte_name(DID_IMM_RETRY), \ > + scsi_hostbyte_name(DID_REQUEUE), \ > + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ > + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) > + > +#define scsi_driverbyte_name(result) { result, #result } > +#define show_driverbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_driverbyte_name(DRIVER_OK), \ > + scsi_driverbyte_name(DRIVER_BUSY), \ > + scsi_driverbyte_name(DRIVER_SOFT), \ > + scsi_driverbyte_name(DRIVER_MEDIA), \ > + scsi_driverbyte_name(DRIVER_ERROR), \ > + scsi_driverbyte_name(DRIVER_INVALID), \ > + scsi_driverbyte_name(DRIVER_TIMEOUT), \ > + scsi_driverbyte_name(DRIVER_HARD), \ > + scsi_driverbyte_name(DRIVER_SENSE)) > + > +#define scsi_msgbyte_name(result) { result, #result } > +#define show_msgbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_msgbyte_name(COMMAND_COMPLETE), \ > + scsi_msgbyte_name(EXTENDED_MESSAGE), \ > + scsi_msgbyte_name(SAVE_POINTERS), \ > + scsi_msgbyte_name(RESTORE_POINTERS), \ > + scsi_msgbyte_name(DISCONNECT), \ > + scsi_msgbyte_name(INITIATOR_ERROR), \ > + scsi_msgbyte_name(ABORT_TASK_SET), \ > + scsi_msgbyte_name(MESSAGE_REJECT), \ > + scsi_msgbyte_name(NOP), \ > + scsi_msgbyte_name(MSG_PARITY_ERROR), \ > + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ > + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ > + scsi_msgbyte_name(TARGET_RESET), \ > + scsi_msgbyte_name(ABORT_TASK), \ > + scsi_msgbyte_name(CLEAR_TASK_SET), \ > + scsi_msgbyte_name(INITIATE_RECOVERY), \ > + scsi_msgbyte_name(RELEASE_RECOVERY), \ > + scsi_msgbyte_name(CLEAR_ACA), \ > + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ > + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ > + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ > + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ > + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ > + scsi_msgbyte_name(ACA), \ > + scsi_msgbyte_name(QAS_REQUEST), \ > + scsi_msgbyte_name(BUS_DEVICE_RESET), \ > + scsi_msgbyte_name(ABORT)) > + > +#define scsi_statusbyte_name(result) { result, #result } > +#define show_statusbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_statusbyte_name(SAM_STAT_GOOD), \ > + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ > + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_BUSY), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ > + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ > + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ > + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ > + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) > + > +#define scsi_prot_op_name(result) { result, #result } > +#define show_prot_op_name(val) \ > + __print_symbolic(val, \ > + scsi_prot_op_name(SCSI_PROT_NORMAL), \ > + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) > + > +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); > +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) > +#endif > + > +TRACE_EVENT(scsi_dispatch_cmd_start, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, cmd->device->host->host_no); > + tp_assign(channel, cmd->device->channel); > + tp_assign(id, cmd->device->id); > + tp_assign(lun, cmd->device->lun); > + tp_assign(opcode, cmd->cmnd[0]); > + tp_assign(cmd_len, cmd->cmd_len); > + tp_assign(data_sglen, scsi_sg_count(cmd)); > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > + tp_assign(prot_op, scsi_get_prot_op(cmd)); > + tp_memcpy_dyn(cmnd, cmd->cmnd); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) > +) > + > +TRACE_EVENT(scsi_dispatch_cmd_error, > + > + TP_PROTO(struct scsi_cmnd *cmd, int rtn), > + > + TP_ARGS(cmd, rtn), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, rtn ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, cmd->device->host->host_no); > + tp_assign(channel, cmd->device->channel); > + tp_assign(id, cmd->device->id); > + tp_assign(lun, cmd->device->lun); > + tp_assign(rtn, rtn); > + tp_assign(opcode, cmd->cmnd[0]); > + tp_assign(cmd_len, cmd->cmd_len); > + tp_assign(data_sglen, scsi_sg_count(cmd)); > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > + tp_assign(prot_op, scsi_get_prot_op(cmd)); > + tp_memcpy_dyn(cmnd, cmd->cmnd); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + __entry->rtn) > +) > + > +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, result ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, cmd->device->host->host_no); > + tp_assign(channel, cmd->device->channel); > + tp_assign(id, cmd->device->id); > + tp_assign(lun, cmd->device->lun); > + tp_assign(result, cmd->result); > + tp_assign(opcode, cmd->cmnd[0]); > + tp_assign(cmd_len, cmd->cmd_len); > + tp_assign(data_sglen, scsi_sg_count(cmd)); > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > + tp_assign(prot_op, scsi_get_prot_op(cmd)); > + tp_memcpy_dyn(cmnd, cmd->cmnd); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ > + "%s host=%s message=%s status=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + show_driverbyte_name(((__entry->result) >> 24) & 0xff), > + show_hostbyte_name(((__entry->result) >> 16) & 0xff), > + show_msgbyte_name(((__entry->result) >> 8) & 0xff), > + show_statusbyte_name(__entry->result & 0xff)) > +) > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)) > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)) > + > +TRACE_EVENT(scsi_eh_wakeup, > + > + TP_PROTO(struct Scsi_Host *shost), > + > + TP_ARGS(shost), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + ), > + > + TP_fast_assign( > + tp_assign(host_no, shost->host_no); > + ), > + > + TP_printk("host_no=%u", __entry->host_no) > +) > + > +#endif /* _TRACE_SCSI_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/skb.h b/instrumentation/events/lttng-module/skb.h > new file mode 100644 > index 0000000..9a79449 > --- /dev/null > +++ b/instrumentation/events/lttng-module/skb.h > @@ -0,0 +1,75 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM skb > + > +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SKB_H > + > +#include > +#include > +#include > + > +/* > + * Tracepoint for free an sk_buff: > + */ > +TRACE_EVENT(kfree_skb, > + > + TP_PROTO(struct sk_buff *skb, void *location), > + > + TP_ARGS(skb, location), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( void *, location ) > + __field( unsigned short, protocol ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(location, location); > + tp_assign(protocol, ntohs(skb->protocol)); > + ), > + > + TP_printk("skbaddr=%p protocol=%u location=%p", > + __entry->skbaddr, __entry->protocol, __entry->location) > +) > + > +TRACE_EVENT(consume_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + ), > + > + TP_printk("skbaddr=%p", __entry->skbaddr) > +) > + > +TRACE_EVENT(skb_copy_datagram_iovec, > + > + TP_PROTO(const struct sk_buff *skb, int len), > + > + TP_ARGS(skb, len), > + > + TP_STRUCT__entry( > + __field( const void *, skbaddr ) > + __field( int, len ) > + ), > + > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, len); > + ), > + > + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) > +) > + > +#endif /* _TRACE_SKB_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h > new file mode 100644 > index 0000000..246ea58 > --- /dev/null > +++ b/instrumentation/events/lttng-module/sock.h > @@ -0,0 +1,68 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM sock > + > +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SOCK_H > + > +#include > +#include > + > +TRACE_EVENT(sock_rcvqueue_full, > + > + TP_PROTO(struct sock *sk, struct sk_buff *skb), > + > + TP_ARGS(sk, skb), > + > + TP_STRUCT__entry( > + __field(int, rmem_alloc) > + __field(unsigned int, truesize) > + __field(int, sk_rcvbuf) > + ), > + > + TP_fast_assign( > + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > + tp_assign(truesize, skb->truesize); > + tp_assign(sk_rcvbuf, sk->sk_rcvbuf); > + ), > + > + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", > + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) > +) > + > +TRACE_EVENT(sock_exceed_buf_limit, > + > + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), > + > + TP_ARGS(sk, prot, allocated), > + > + TP_STRUCT__entry( > + __string(name, prot->name) > + __field(long *, sysctl_mem) > + __field(long, allocated) > + __field(int, sysctl_rmem) > + __field(int, rmem_alloc) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, prot->name); > + tp_assign(sysctl_mem, prot->sysctl_mem); > + tp_assign(allocated, allocated); > + tp_assign(sysctl_rmem, prot->sysctl_rmem[0]); > + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > + ), > + > + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " > + "sysctl_rmem=%d rmem_alloc=%d", > + __entry->name, > + __entry->sysctl_mem[0], > + __entry->sysctl_mem[1], > + __entry->sysctl_mem[2], > + __entry->allocated, > + __entry->sysctl_rmem, > + __entry->rmem_alloc) > +) > + > +#endif /* _TRACE_SOCK_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/udp.h b/instrumentation/events/lttng-module/udp.h > new file mode 100644 > index 0000000..304ea95 > --- /dev/null > +++ b/instrumentation/events/lttng-module/udp.h > @@ -0,0 +1,32 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM udp > + > +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_UDP_H > + > +#include > +#include > + > +TRACE_EVENT(udp_fail_queue_rcv_skb, > + > + TP_PROTO(int rc, struct sock *sk), > + > + TP_ARGS(rc, sk), > + > + TP_STRUCT__entry( > + __field(int, rc) > + __field(__u16, lport) > + ), > + > + TP_fast_assign( > + tp_assign(rc, rc); > + tp_assign(lport, inet_sk(sk)->inet_num); > + ), > + > + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) > +) > + > +#endif /* _TRACE_UDP_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h > new file mode 100644 > index 0000000..aa022e2 > --- /dev/null > +++ b/instrumentation/events/lttng-module/vmscan.h > @@ -0,0 +1,499 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM vmscan > + > +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_VMSCAN_H > + > +TRACE_EVENT(mm_vmscan_kswapd_sleep, > + > + TP_PROTO(int nid), > + > + TP_ARGS(nid), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + ), > + > + TP_printk("nid=%d", __entry->nid) > +) > + > +TRACE_EVENT(mm_vmscan_kswapd_wake, > + > + TP_PROTO(int nid, int order), > + > + TP_ARGS(nid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + tp_assign(order, order); > + ), > + > + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) > +) > + > +TRACE_EVENT(mm_vmscan_wakeup_kswapd, > + > + TP_PROTO(int nid, int zid, int order), > + > + TP_ARGS(nid, zid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, zid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + tp_assign(zid, zid); > + tp_assign(order, order); > + ), > + > + TP_printk("nid=%d zid=%d order=%d", > + __entry->nid, > + __entry->zid, > + __entry->order) > +) > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags), > + > + TP_STRUCT__entry( > + __field( int, order ) > + __field( int, may_writepage ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + tp_assign(order, order); > + tp_assign(may_writepage, may_writepage); > + tp_assign(gfp_flags, gfp_flags); > + ), > + > + TP_printk("order=%d may_writepage=%d gfp_flags=%s", > + __entry->order, > + __entry->may_writepage, > + show_gfp_flags(__entry->gfp_flags)) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +) > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed), > + > + TP_STRUCT__entry( > + __field( unsigned long, nr_reclaimed ) > + ), > + > + TP_fast_assign( > + tp_assign(nr_reclaimed, nr_reclaimed); > + ), > + > + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +) > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +) > + > +TRACE_EVENT(mm_shrink_slab_start, > + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, > + long nr_objects_to_shrink, unsigned long pgs_scanned, > + unsigned long lru_pgs, unsigned long cache_items, > + unsigned long long delta, unsigned long total_scan), > + > + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, > + cache_items, delta, total_scan), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, nr_objects_to_shrink) > + __field(gfp_t, gfp_flags) > + __field(unsigned long, pgs_scanned) > + __field(unsigned long, lru_pgs) > + __field(unsigned long, cache_items) > + __field(unsigned long long, delta) > + __field(unsigned long, total_scan) > + ), > + > + TP_fast_assign( > + tp_assign(shr,shr); > + tp_assign(shrink, shr->shrink); > + tp_assign(nr_objects_to_shrink, nr_objects_to_shrink); > + tp_assign(gfp_flags, sc->gfp_mask); > + tp_assign(pgs_scanned, pgs_scanned); > + tp_assign(lru_pgs, lru_pgs); > + tp_assign(cache_items, cache_items); > + tp_assign(delta, delta); > + tp_assign(total_scan, total_scan); > + ), > + > + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", > + __entry->shrink, > + __entry->shr, > + __entry->nr_objects_to_shrink, > + show_gfp_flags(__entry->gfp_flags), > + __entry->pgs_scanned, > + __entry->lru_pgs, > + __entry->cache_items, > + __entry->delta, > + __entry->total_scan) > +) > + > +TRACE_EVENT(mm_shrink_slab_end, > + TP_PROTO(struct shrinker *shr, int shrinker_retval, > + long unused_scan_cnt, long new_scan_cnt), > + > + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, unused_scan) > + __field(long, new_scan) > + __field(int, retval) > + __field(long, total_scan) > + ), > + > + TP_fast_assign( > + tp_assign(shr, shr); > + tp_assign(shrink, shr->shrink); > + tp_assign(unused_scan, unused_scan_cnt); > + tp_assign(new_scan, new_scan_cnt); > + tp_assign(retval, shrinker_retval); > + tp_assign(total_scan, new_scan_cnt - unused_scan_cnt); > + ), > + > + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", > + __entry->shrink, > + __entry->shr, > + __entry->unused_scan, > + __entry->new_scan, > + __entry->total_scan, > + __entry->retval) > +) > + > +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + isolate_mode_t isolate_mode), > +#else > + isolate_mode_t isolate_mode, > + int file), > +#endif > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), > +#else > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file), > +#endif > + > + TP_STRUCT__entry( > + __field(int, order) > + __field(unsigned long, nr_requested) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_taken) > + __field(unsigned long, nr_lumpy_taken) > + __field(unsigned long, nr_lumpy_dirty) > + __field(unsigned long, nr_lumpy_failed) > + __field(isolate_mode_t, isolate_mode) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > + __field(int, file) > +#endif > + ), > + > + TP_fast_assign( > + tp_assign(order, order); > + tp_assign(nr_requested, nr_requested); > + tp_assign(nr_scanned, nr_scanned); > + tp_assign(nr_taken, nr_taken); > + tp_assign(nr_lumpy_taken, nr_lumpy_taken); > + tp_assign(nr_lumpy_dirty, nr_lumpy_dirty); > + tp_assign(nr_lumpy_failed, nr_lumpy_failed); > + tp_assign(isolate_mode, isolate_mode); > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > + tp_assign(file, file); > +#endif > + ), > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", > +#else > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", > +#endif > + __entry->isolate_mode, > + __entry->order, > + __entry->nr_requested, > + __entry->nr_scanned, > + __entry->nr_taken, > + __entry->nr_lumpy_taken, > + __entry->nr_lumpy_dirty, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + __entry->nr_lumpy_failed) > +#else > + __entry->nr_lumpy_failed, > + __entry->file) > +#endif > +) > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > +#endif > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + isolate_mode_t isolate_mode), > +#else > + isolate_mode_t isolate_mode, > + int file), > +#endif > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) > +#else > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > +#endif > + > +) > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > +#endif > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + isolate_mode_t isolate_mode), > +#else > + isolate_mode_t isolate_mode, > + int file), > +#endif > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) > +#else > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > +#endif > + > +) > + > +TRACE_EVENT(mm_vmscan_writepage, > + > + TP_PROTO(struct page *page, > + int reclaim_flags), > + > + TP_ARGS(page, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(struct page *, page) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + tp_assign(page, page); > + tp_assign(reclaim_flags, reclaim_flags); > + ), > + > + TP_printk("page=%p pfn=%lu flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + show_reclaim_flags(__entry->reclaim_flags)) > +) > + > +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > + > + TP_PROTO(int nid, int zid, > + unsigned long nr_scanned, unsigned long nr_reclaimed, > + int priority, int reclaim_flags), > + > + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(int, nid) > + __field(int, zid) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_reclaimed) > + __field(int, priority) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + tp_assign(nid, nid); > + tp_assign(zid, zid); > + tp_assign(nr_scanned, nr_scanned); > + tp_assign(nr_reclaimed, nr_reclaimed); > + tp_assign(priority, priority); > + tp_assign(reclaim_flags, reclaim_flags); > + ), > + > + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", > + __entry->nid, __entry->zid, > + __entry->nr_scanned, __entry->nr_reclaimed, > + __entry->priority, > + show_reclaim_flags(__entry->reclaim_flags)) > +) > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + > +TRACE_EVENT(replace_swap_token, > + TP_PROTO(struct mm_struct *old_mm, > + struct mm_struct *new_mm), > + > + TP_ARGS(old_mm, new_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, old_mm) > + __field(unsigned int, old_prio) > + __field(struct mm_struct*, new_mm) > + __field(unsigned int, new_prio) > + ), > + > + TP_fast_assign( > + tp_assign(old_mm, old_mm); > + tp_assign(old_prio, old_mm ? old_mm->token_priority : 0); > + tp_assign(new_mm, new_mm); > + tp_assign(new_prio, new_mm->token_priority); > + ), > + > + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", > + __entry->old_mm, __entry->old_prio, > + __entry->new_mm, __entry->new_prio) > +) > + > +DECLARE_EVENT_CLASS(put_swap_token_template, > + TP_PROTO(struct mm_struct *swap_token_mm), > + > + TP_ARGS(swap_token_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, swap_token_mm) > + ), > + > + TP_fast_assign( > + tp_assign(swap_token_mm, swap_token_mm); > + ), > + > + TP_printk("token_mm=%p", __entry->swap_token_mm) > +) > + > +DEFINE_EVENT(put_swap_token_template, put_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm) > +) > + > +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm), > + TP_CONDITION(swap_token_mm != NULL) > +) > + > +TRACE_EVENT_CONDITION(update_swap_token_priority, > + TP_PROTO(struct mm_struct *mm, > + unsigned int old_prio, > + struct mm_struct *swap_token_mm), > + > + TP_ARGS(mm, old_prio, swap_token_mm), > + > + TP_CONDITION(mm->token_priority != old_prio), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, mm) > + __field(unsigned int, old_prio) > + __field(unsigned int, new_prio) > + __field(struct mm_struct*, swap_token_mm) > + __field(unsigned int, swap_token_prio) > + ), > + > + TP_fast_assign( > + tp_assign(mm, mm); > + tp_assign(old_prio, old_prio); > + tp_assign(new_prio, mm->token_priority); > + tp_assign(swap_token_mm, swap_token_mm); > + tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0); > + ), > + > + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", > + __entry->mm, __entry->old_prio, __entry->new_prio, > + __entry->swap_token_mm, __entry->swap_token_prio) > +) > + > +#endif > + > +#endif /* _TRACE_VMSCAN_H */ > + > +/* This part must be outside protection */ > +#include "../../../probes/define_trace.h" > diff --git a/instrumentation/events/mainline/asoc.h b/instrumentation/events/mainline/asoc.h > new file mode 100644 > index 0000000..ab26f8a > --- /dev/null > +++ b/instrumentation/events/mainline/asoc.h > @@ -0,0 +1,330 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM asoc > + > +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_ASOC_H > + > +#include > +#include > + > +struct snd_soc_jack; > +struct snd_soc_codec; > +struct snd_soc_platform; > +struct snd_soc_card; > +struct snd_soc_dapm_widget; > + > +/* > + * Log register events > + */ > +DECLARE_EVENT_CLASS(snd_soc_reg, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, codec->name); > + __entry->id = codec->id; > + __entry->reg = reg; > + __entry->val = val; > + ), > + > + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +); > + > +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, > + > + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(codec, reg, val) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_preg, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val), > + > + TP_STRUCT__entry( > + __string( name, platform->name ) > + __field( int, id ) > + __field( unsigned int, reg ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, platform->name); > + __entry->id = platform->id; > + __entry->reg = reg; > + __entry->val = val; > + ), > + > + TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), > + (int)__entry->id, (unsigned int)__entry->reg, > + (unsigned int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +); > + > +DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, > + > + TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, > + unsigned int val), > + > + TP_ARGS(platform, reg, val) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_card, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, card->name); > + __entry->val = val; > + ), > + > + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +); > + > +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, > + > + TP_PROTO(struct snd_soc_card *card, int val), > + > + TP_ARGS(card, val) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, card->name); > + ), > + > + TP_printk("card=%s", __get_str(name)) > +); > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +); > + > +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card) > + > +); > + > +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val), > + > + TP_STRUCT__entry( > + __string( name, w->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, w->name); > + __entry->val = val; > + ), > + > + TP_printk("widget=%s val=%d", __get_str(name), > + (int)__entry->val) > +); > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +); > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +); > + > +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, > + > + TP_PROTO(struct snd_soc_dapm_widget *w, int val), > + > + TP_ARGS(w, val) > + > +); > + > +TRACE_EVENT(snd_soc_dapm_walk_done, > + > + TP_PROTO(struct snd_soc_card *card), > + > + TP_ARGS(card), > + > + TP_STRUCT__entry( > + __string( name, card->name ) > + __field( int, power_checks ) > + __field( int, path_checks ) > + __field( int, neighbour_checks ) > + ), > + > + TP_fast_assign( > + __assign_str(name, card->name); > + __entry->power_checks = card->dapm_stats.power_checks; > + __entry->path_checks = card->dapm_stats.path_checks; > + __entry->neighbour_checks = card->dapm_stats.neighbour_checks; > + ), > + > + TP_printk("%s: checks %d power, %d path, %d neighbour", > + __get_str(name), (int)__entry->power_checks, > + (int)__entry->path_checks, (int)__entry->neighbour_checks) > +); > + > +TRACE_EVENT(snd_soc_jack_irq, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + ), > + > + TP_printk("%s", __get_str(name)) > +); > + > +TRACE_EVENT(snd_soc_jack_report, > + > + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), > + > + TP_ARGS(jack, mask, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, mask ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, jack->jack->name); > + __entry->mask = mask; > + __entry->val = val; > + ), > + > + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, > + (int)__entry->mask) > +); > + > +TRACE_EVENT(snd_soc_jack_notify, > + > + TP_PROTO(struct snd_soc_jack *jack, int val), > + > + TP_ARGS(jack, val), > + > + TP_STRUCT__entry( > + __string( name, jack->jack->name ) > + __field( int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, jack->jack->name); > + __entry->val = val; > + ), > + > + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) > +); > + > +TRACE_EVENT(snd_soc_cache_sync, > + > + TP_PROTO(struct snd_soc_codec *codec, const char *type, > + const char *status), > + > + TP_ARGS(codec, type, status), > + > + TP_STRUCT__entry( > + __string( name, codec->name ) > + __string( status, status ) > + __string( type, type ) > + __field( int, id ) > + ), > + > + TP_fast_assign( > + __assign_str(name, codec->name); > + __assign_str(status, status); > + __assign_str(type, type); > + __entry->id = codec->id; > + ), > + > + TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), > + (int)__entry->id, __get_str(type), __get_str(status)) > +); > + > +#endif /* _TRACE_ASOC_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/ext3.h b/instrumentation/events/mainline/ext3.h > new file mode 100644 > index 0000000..7b53c05 > --- /dev/null > +++ b/instrumentation/events/mainline/ext3.h > @@ -0,0 +1,864 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM ext3 > + > +#if !defined(_TRACE_EXT3_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_EXT3_H > + > +#include > + > +TRACE_EVENT(ext3_free_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( uid_t, uid ) > + __field( gid_t, gid ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->mode = inode->i_mode; > + __entry->uid = inode->i_uid; > + __entry->gid = inode->i_gid; > + __entry->blocks = inode->i_blocks; > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->uid, __entry->gid, > + (unsigned long) __entry->blocks) > +); > + > +TRACE_EVENT(ext3_request_inode, > + TP_PROTO(struct inode *dir, int mode), > + > + TP_ARGS(dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + __entry->dev = dir->i_sb->s_dev; > + __entry->dir = dir->i_ino; > + __entry->mode = mode; > + ), > + > + TP_printk("dev %d,%d dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->dir, __entry->mode) > +); > + > +TRACE_EVENT(ext3_allocate_inode, > + TP_PROTO(struct inode *inode, struct inode *dir, int mode), > + > + TP_ARGS(inode, dir, mode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, dir ) > + __field( umode_t, mode ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->dir = dir->i_ino; > + __entry->mode = mode; > + ), > + > + TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->dir, __entry->mode) > +); > + > +TRACE_EVENT(ext3_evict_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, nlink ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->nlink = inode->i_nlink; > + ), > + > + TP_printk("dev %d,%d ino %lu nlink %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->nlink) > +); > + > +TRACE_EVENT(ext3_drop_inode, > + TP_PROTO(struct inode *inode, int drop), > + > + TP_ARGS(inode, drop), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( int, drop ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->drop = drop; > + ), > + > + TP_printk("dev %d,%d ino %lu drop %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->drop) > +); > + > +TRACE_EVENT(ext3_mark_inode_dirty, > + TP_PROTO(struct inode *inode, unsigned long IP), > + > + TP_ARGS(inode, IP), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field(unsigned long, ip ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->ip = IP; > + ), > + > + TP_printk("dev %d,%d ino %lu caller %pF", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (void *)__entry->ip) > +); > + > +TRACE_EVENT(ext3_write_begin, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int flags), > + > + TP_ARGS(inode, pos, len, flags), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, flags ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->pos = pos; > + __entry->len = len; > + __entry->flags = flags; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->flags) > +); > + > +DECLARE_EVENT_CLASS(ext3__write_end, > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( loff_t, pos ) > + __field( unsigned int, len ) > + __field( unsigned int, copied ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->pos = pos; > + __entry->len = len; > + __entry->copied = copied; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->copied) > +); > + > +DEFINE_EVENT(ext3__write_end, ext3_ordered_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +); > + > +DEFINE_EVENT(ext3__write_end, ext3_writeback_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +); > + > +DEFINE_EVENT(ext3__write_end, ext3_journalled_write_end, > + > + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, > + unsigned int copied), > + > + TP_ARGS(inode, pos, len, copied) > +); > + > +DECLARE_EVENT_CLASS(ext3__page_op, > + TP_PROTO(struct page *page), > + > + TP_ARGS(page), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( pgoff_t, index ) > + > + ), > + > + TP_fast_assign( > + __entry->index = page->index; > + __entry->ino = page->mapping->host->i_ino; > + __entry->dev = page->mapping->host->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, __entry->index) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_ordered_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_writeback_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_journalled_writepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_readpage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +DEFINE_EVENT(ext3__page_op, ext3_releasepage, > + > + TP_PROTO(struct page *page), > + > + TP_ARGS(page) > +); > + > +TRACE_EVENT(ext3_invalidatepage, > + TP_PROTO(struct page *page, unsigned long offset), > + > + TP_ARGS(page, offset), > + > + TP_STRUCT__entry( > + __field( pgoff_t, index ) > + __field( unsigned long, offset ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + > + ), > + > + TP_fast_assign( > + __entry->index = page->index; > + __entry->offset = offset; > + __entry->ino = page->mapping->host->i_ino; > + __entry->dev = page->mapping->host->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->index, __entry->offset) > +); > + > +TRACE_EVENT(ext3_discard_blocks, > + TP_PROTO(struct super_block *sb, unsigned long blk, > + unsigned long count), > + > + TP_ARGS(sb, blk, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, blk ) > + __field( unsigned long, count ) > + > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->blk = blk; > + __entry->count = count; > + ), > + > + TP_printk("dev %d,%d blk %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->blk, __entry->count) > +); > + > +TRACE_EVENT(ext3_request_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count), > + > + TP_ARGS(inode, goal, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->count = count; > + __entry->goal = goal; > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu goal %lu ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->goal) > +); > + > +TRACE_EVENT(ext3_allocate_blocks, > + TP_PROTO(struct inode *inode, unsigned long goal, > + unsigned long count, unsigned long block), > + > + TP_ARGS(inode, goal, count, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->block = block; > + __entry->count = count; > + __entry->goal = goal; > + ), > + > + TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->count, __entry->block, > + __entry->goal) > +); > + > +TRACE_EVENT(ext3_free_blocks, > + TP_PROTO(struct inode *inode, unsigned long block, > + unsigned long count), > + > + TP_ARGS(inode, block, count), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( unsigned long, block ) > + __field( unsigned long, count ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->mode = inode->i_mode; > + __entry->block = block; > + __entry->count = count; > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->block, __entry->count) > +); > + > +TRACE_EVENT(ext3_sync_file_enter, > + TP_PROTO(struct file *file, int datasync), > + > + TP_ARGS(file, datasync), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( ino_t, parent ) > + __field( int, datasync ) > + ), > + > + TP_fast_assign( > + struct dentry *dentry = file->f_path.dentry; > + > + __entry->dev = dentry->d_inode->i_sb->s_dev; > + __entry->ino = dentry->d_inode->i_ino; > + __entry->datasync = datasync; > + __entry->parent = dentry->d_parent->d_inode->i_ino; > + ), > + > + TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long) __entry->parent, __entry->datasync) > +); > + > +TRACE_EVENT(ext3_sync_file_exit, > + TP_PROTO(struct inode *inode, int ret), > + > + TP_ARGS(inode, ret), > + > + TP_STRUCT__entry( > + __field( int, ret ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->ret = ret; > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +); > + > +TRACE_EVENT(ext3_sync_fs, > + TP_PROTO(struct super_block *sb, int wait), > + > + TP_ARGS(sb, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->wait = wait; > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +); > + > +TRACE_EVENT(ext3_rsv_window_add, > + TP_PROTO(struct super_block *sb, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->start = rsv_node->rsv_window._rsv_start; > + __entry->end = rsv_node->rsv_window._rsv_end; > + ), > + > + TP_printk("dev %d,%d start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->start, __entry->end) > +); > + > +TRACE_EVENT(ext3_discard_reservation, > + TP_PROTO(struct inode *inode, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(inode, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->start = rsv_node->rsv_window._rsv_start; > + __entry->end = rsv_node->rsv_window._rsv_end; > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long)__entry->ino, __entry->start, > + __entry->end) > +); > + > +TRACE_EVENT(ext3_alloc_new_reservation, > + TP_PROTO(struct super_block *sb, unsigned long goal), > + > + TP_ARGS(sb, goal), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, goal ) > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->goal = goal; > + ), > + > + TP_printk("dev %d,%d goal %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->goal) > +); > + > +TRACE_EVENT(ext3_reserved, > + TP_PROTO(struct super_block *sb, unsigned long block, > + struct ext3_reserve_window_node *rsv_node), > + > + TP_ARGS(sb, block, rsv_node), > + > + TP_STRUCT__entry( > + __field( unsigned long, block ) > + __field( unsigned long, start ) > + __field( unsigned long, end ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->block = block; > + __entry->start = rsv_node->rsv_window._rsv_start; > + __entry->end = rsv_node->rsv_window._rsv_end; > + __entry->dev = sb->s_dev; > + ), > + > + TP_printk("dev %d,%d block %lu, start %lu end %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->block, __entry->start, __entry->end) > +); > + > +TRACE_EVENT(ext3_forget, > + TP_PROTO(struct inode *inode, int is_metadata, unsigned long block), > + > + TP_ARGS(inode, is_metadata, block), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + __field( umode_t, mode ) > + __field( int, is_metadata ) > + __field( unsigned long, block ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + __entry->mode = inode->i_mode; > + __entry->is_metadata = is_metadata; > + __entry->block = block; > + ), > + > + TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->mode, __entry->is_metadata, __entry->block) > +); > + > +TRACE_EVENT(ext3_read_block_bitmap, > + TP_PROTO(struct super_block *sb, unsigned int group), > + > + TP_ARGS(sb, group), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( __u32, group ) > + > + ), > + > + TP_fast_assign( > + __entry->dev = sb->s_dev; > + __entry->group = group; > + ), > + > + TP_printk("dev %d,%d group %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->group) > +); > + > +TRACE_EVENT(ext3_direct_IO_enter, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, int rw), > + > + TP_ARGS(inode, offset, len, rw), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->pos = offset; > + __entry->len = len; > + __entry->rw = rw; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw) > +); > + > +TRACE_EVENT(ext3_direct_IO_exit, > + TP_PROTO(struct inode *inode, loff_t offset, unsigned long len, > + int rw, int ret), > + > + TP_ARGS(inode, offset, len, rw, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( loff_t, pos ) > + __field( unsigned long, len ) > + __field( int, rw ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->pos = offset; > + __entry->len = len; > + __entry->rw = rw; > + __entry->ret = ret; > + ), > + > + TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long) __entry->pos, __entry->len, > + __entry->rw, __entry->ret) > +); > + > +TRACE_EVENT(ext3_unlink_enter, > + TP_PROTO(struct inode *parent, struct dentry *dentry), > + > + TP_ARGS(parent, dentry), > + > + TP_STRUCT__entry( > + __field( ino_t, parent ) > + __field( ino_t, ino ) > + __field( loff_t, size ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->parent = parent->i_ino; > + __entry->ino = dentry->d_inode->i_ino; > + __entry->size = dentry->d_inode->i_size; > + __entry->dev = dentry->d_inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu size %lld parent %ld", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + (unsigned long long)__entry->size, > + (unsigned long) __entry->parent) > +); > + > +TRACE_EVENT(ext3_unlink_exit, > + TP_PROTO(struct dentry *dentry, int ret), > + > + TP_ARGS(dentry, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ino = dentry->d_inode->i_ino; > + __entry->dev = dentry->d_inode->i_sb->s_dev; > + __entry->ret = ret; > + ), > + > + TP_printk("dev %d,%d ino %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->ret) > +); > + > +DECLARE_EVENT_CLASS(ext3__truncate, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( blkcnt_t, blocks ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->blocks = inode->i_blocks; > + ), > + > + TP_printk("dev %d,%d ino %lu blocks %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, (unsigned long) __entry->blocks) > +); > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_enter, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +); > + > +DEFINE_EVENT(ext3__truncate, ext3_truncate_exit, > + > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode) > +); > + > +TRACE_EVENT(ext3_get_blocks_enter, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long len, int create), > + > + TP_ARGS(inode, lblk, len, create), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, len ) > + __field( int, create ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->lblk = lblk; > + __entry->len = len; > + __entry->create = create; > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->len, __entry->create) > +); > + > +TRACE_EVENT(ext3_get_blocks_exit, > + TP_PROTO(struct inode *inode, unsigned long lblk, > + unsigned long pblk, unsigned long len, int ret), > + > + TP_ARGS(inode, lblk, pblk, len, ret), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + __field( unsigned long, lblk ) > + __field( unsigned long, pblk ) > + __field( unsigned long, len ) > + __field( int, ret ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + __entry->lblk = lblk; > + __entry->pblk = pblk; > + __entry->len = len; > + __entry->ret = ret; > + ), > + > + TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino, > + __entry->lblk, __entry->pblk, > + __entry->len, __entry->ret) > +); > + > +TRACE_EVENT(ext3_load_inode, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( ino_t, ino ) > + __field( dev_t, dev ) > + ), > + > + TP_fast_assign( > + __entry->ino = inode->i_ino; > + __entry->dev = inode->i_sb->s_dev; > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +); > + > +#endif /* _TRACE_EXT3_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/fs_ext3.h b/instrumentation/events/mainline/fs_ext3.h > new file mode 100644 > index 0000000..76353e4 > --- /dev/null > +++ b/instrumentation/events/mainline/fs_ext3.h > @@ -0,0 +1,1323 @@ > +/* > + * Written by Stephen C. Tweedie , 1999 > + * > + * Copyright 1998--1999 Red Hat corp --- All Rights Reserved > + * > + * This file is part of the Linux kernel and is made available under > + * the terms of the GNU General Public License, version 2, or at your > + * option, any later version, incorporated herein by reference. > + * > + * Copyright (C) 1992, 1993, 1994, 1995 > + * Remy Card (card at masi.ibp.fr) > + * Laboratoire MASI - Institut Blaise Pascal > + * Universite Pierre et Marie Curie (Paris VI) > + * > + * from > + * > + * linux/include/linux/minix_fs.h > + * > + * Copyright (C) 1991, 1992 Linus Torvalds > + */ > + > +#include > +#include > +#include > +#include > +#include > + > +/* > + * The second extended filesystem constants/structures > + */ > + > +/* > + * Define EXT3FS_DEBUG to produce debug messages > + */ > +#undef EXT3FS_DEBUG > + > +/* > + * Define EXT3_RESERVATION to reserve data blocks for expanding files > + */ > +#define EXT3_DEFAULT_RESERVE_BLOCKS 8 > +/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ > +#define EXT3_MAX_RESERVE_BLOCKS 1027 > +#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 > + > +/* > + * Debug code > + */ > +#ifdef EXT3FS_DEBUG > +#define ext3_debug(f, a...) \ > + do { \ > + printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ > + __FILE__, __LINE__, __func__); \ > + printk (KERN_DEBUG f, ## a); \ > + } while (0) > +#else > +#define ext3_debug(f, a...) do {} while (0) > +#endif > + > +/* > + * Special inodes numbers > + */ > +#define EXT3_BAD_INO 1 /* Bad blocks inode */ > +#define EXT3_ROOT_INO 2 /* Root inode */ > +#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ > +#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ > +#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ > +#define EXT3_JOURNAL_INO 8 /* Journal inode */ > + > +/* First non-reserved inode for old ext3 filesystems */ > +#define EXT3_GOOD_OLD_FIRST_INO 11 > + > +/* > + * Maximal count of links to a file > + */ > +#define EXT3_LINK_MAX 32000 > + > +/* > + * Macro-instructions used to manage several block sizes > + */ > +#define EXT3_MIN_BLOCK_SIZE 1024 > +#define EXT3_MAX_BLOCK_SIZE 65536 > +#define EXT3_MIN_BLOCK_LOG_SIZE 10 > +#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) > +#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) > +#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) > +#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) > +#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) > +#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) > + > +/* > + * Macro-instructions used to manage fragments > + */ > +#define EXT3_MIN_FRAG_SIZE 1024 > +#define EXT3_MAX_FRAG_SIZE 4096 > +#define EXT3_MIN_FRAG_LOG_SIZE 10 > +#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) > +#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) > + > +/* > + * Structure of a blocks group descriptor > + */ > +struct ext3_group_desc > +{ > + __le32 bg_block_bitmap; /* Blocks bitmap block */ > + __le32 bg_inode_bitmap; /* Inodes bitmap block */ > + __le32 bg_inode_table; /* Inodes table block */ > + __le16 bg_free_blocks_count; /* Free blocks count */ > + __le16 bg_free_inodes_count; /* Free inodes count */ > + __le16 bg_used_dirs_count; /* Directories count */ > + __u16 bg_pad; > + __le32 bg_reserved[3]; > +}; > + > +/* > + * Macro-instructions used to manage group descriptors > + */ > +#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) > +#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) > +#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) > +#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) > + > +/* > + * Constants relative to the data blocks > + */ > +#define EXT3_NDIR_BLOCKS 12 > +#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS > +#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1) > +#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1) > +#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1) > + > +/* > + * Inode flags > + */ > +#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */ > +#define EXT3_UNRM_FL 0x00000002 /* Undelete */ > +#define EXT3_COMPR_FL 0x00000004 /* Compress file */ > +#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */ > +#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */ > +#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */ > +#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */ > +#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */ > +/* Reserved for compression usage... */ > +#define EXT3_DIRTY_FL 0x00000100 > +#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ > +#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */ > +#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */ > +/* End compression flags --- maybe not all used */ > +#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */ > +#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ > +#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ > +#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ > +#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ > +#define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ > +#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ > + > +#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ > +#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ > + > +/* Flags that should be inherited by new inodes from their parent. */ > +#define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ > + EXT3_SYNC_FL | EXT3_NODUMP_FL |\ > + EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\ > + EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\ > + EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL) > + > +/* Flags that are appropriate for regular files (all but dir-specific ones). */ > +#define EXT3_REG_FLMASK (~(EXT3_DIRSYNC_FL | EXT3_TOPDIR_FL)) > + > +/* Flags that are appropriate for non-directories/regular files. */ > +#define EXT3_OTHER_FLMASK (EXT3_NODUMP_FL | EXT3_NOATIME_FL) > + > +/* Mask out flags that are inappropriate for the given type of inode. */ > +static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) > +{ > + if (S_ISDIR(mode)) > + return flags; > + else if (S_ISREG(mode)) > + return flags & EXT3_REG_FLMASK; > + else > + return flags & EXT3_OTHER_FLMASK; > +} > + > +/* Used to pass group descriptor data when online resize is done */ > +struct ext3_new_group_input { > + __u32 group; /* Group number for this data */ > + __u32 block_bitmap; /* Absolute block number of block bitmap */ > + __u32 inode_bitmap; /* Absolute block number of inode bitmap */ > + __u32 inode_table; /* Absolute block number of inode table start */ > + __u32 blocks_count; /* Total number of blocks in this group */ > + __u16 reserved_blocks; /* Number of reserved blocks in this group */ > + __u16 unused; > +}; > + > +/* The struct ext3_new_group_input in kernel space, with free_blocks_count */ > +struct ext3_new_group_data { > + __u32 group; > + __u32 block_bitmap; > + __u32 inode_bitmap; > + __u32 inode_table; > + __u32 blocks_count; > + __u16 reserved_blocks; > + __u16 unused; > + __u32 free_blocks_count; > +}; > + > + > +/* > + * ioctl commands > + */ > +#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS > +#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS > +#define EXT3_IOC_GETVERSION _IOR('f', 3, long) > +#define EXT3_IOC_SETVERSION _IOW('f', 4, long) > +#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) > +#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input) > +#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION > +#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION > +#ifdef CONFIG_JBD_DEBUG > +#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) > +#endif > +#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) > +#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long) > + > +/* > + * ioctl commands in 32 bit emulation > + */ > +#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS > +#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS > +#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) > +#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) > +#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) > +#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) > +#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) > +#ifdef CONFIG_JBD_DEBUG > +#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) > +#endif > +#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION > +#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION > + > + > +/* > + * Mount options > + */ > +struct ext3_mount_options { > + unsigned long s_mount_opt; > + uid_t s_resuid; > + gid_t s_resgid; > + unsigned long s_commit_interval; > +#ifdef CONFIG_QUOTA > + int s_jquota_fmt; > + char *s_qf_names[MAXQUOTAS]; > +#endif > +}; > + > +/* > + * Structure of an inode on the disk > + */ > +struct ext3_inode { > + __le16 i_mode; /* File mode */ > + __le16 i_uid; /* Low 16 bits of Owner Uid */ > + __le32 i_size; /* Size in bytes */ > + __le32 i_atime; /* Access time */ > + __le32 i_ctime; /* Creation time */ > + __le32 i_mtime; /* Modification time */ > + __le32 i_dtime; /* Deletion Time */ > + __le16 i_gid; /* Low 16 bits of Group Id */ > + __le16 i_links_count; /* Links count */ > + __le32 i_blocks; /* Blocks count */ > + __le32 i_flags; /* File flags */ > + union { > + struct { > + __u32 l_i_reserved1; > + } linux1; > + struct { > + __u32 h_i_translator; > + } hurd1; > + struct { > + __u32 m_i_reserved1; > + } masix1; > + } osd1; /* OS dependent 1 */ > + __le32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */ > + __le32 i_generation; /* File version (for NFS) */ > + __le32 i_file_acl; /* File ACL */ > + __le32 i_dir_acl; /* Directory ACL */ > + __le32 i_faddr; /* Fragment address */ > + union { > + struct { > + __u8 l_i_frag; /* Fragment number */ > + __u8 l_i_fsize; /* Fragment size */ > + __u16 i_pad1; > + __le16 l_i_uid_high; /* these 2 fields */ > + __le16 l_i_gid_high; /* were reserved2[0] */ > + __u32 l_i_reserved2; > + } linux2; > + struct { > + __u8 h_i_frag; /* Fragment number */ > + __u8 h_i_fsize; /* Fragment size */ > + __u16 h_i_mode_high; > + __u16 h_i_uid_high; > + __u16 h_i_gid_high; > + __u32 h_i_author; > + } hurd2; > + struct { > + __u8 m_i_frag; /* Fragment number */ > + __u8 m_i_fsize; /* Fragment size */ > + __u16 m_pad1; > + __u32 m_i_reserved2[2]; > + } masix2; > + } osd2; /* OS dependent 2 */ > + __le16 i_extra_isize; > + __le16 i_pad1; > +}; > + > +#define i_size_high i_dir_acl > + > +#define i_reserved1 osd1.linux1.l_i_reserved1 > +#define i_frag osd2.linux2.l_i_frag > +#define i_fsize osd2.linux2.l_i_fsize > +#define i_uid_low i_uid > +#define i_gid_low i_gid > +#define i_uid_high osd2.linux2.l_i_uid_high > +#define i_gid_high osd2.linux2.l_i_gid_high > +#define i_reserved2 osd2.linux2.l_i_reserved2 > + > +/* > + * File system states > + */ > +#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */ > +#define EXT3_ERROR_FS 0x0002 /* Errors detected */ > +#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */ > + > +/* > + * Misc. filesystem flags > + */ > +#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ > +#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ > +#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ > + > +/* > + * Mount flags > + */ > +#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */ > +/* EXT3_MOUNT_OLDALLOC was there */ > +#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */ > +#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */ > +#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ > +#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ > +#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ > +#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ > +#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ > +#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */ > +#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ > +#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ > +#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ > +#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ > +#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ > +#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ > +#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ > +#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ > +#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ > +#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ > +#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ > +#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ > +#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ > +#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write > + * error in ordered mode */ > + > +/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ > +#ifndef _LINUX_EXT2_FS_H > +#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt > +#define set_opt(o, opt) o |= EXT3_MOUNT_##opt > +#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ > + EXT3_MOUNT_##opt) > +#else > +#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD > +#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT > +#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS > +#endif > + > +#define ext3_set_bit __set_bit_le > +#define ext3_set_bit_atomic ext2_set_bit_atomic > +#define ext3_clear_bit __clear_bit_le > +#define ext3_clear_bit_atomic ext2_clear_bit_atomic > +#define ext3_test_bit test_bit_le > +#define ext3_find_next_zero_bit find_next_zero_bit_le > + > +/* > + * Maximal mount counts between two filesystem checks > + */ > +#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ > +#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */ > + > +/* > + * Behaviour when detecting errors > + */ > +#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */ > +#define EXT3_ERRORS_RO 2 /* Remount fs read-only */ > +#define EXT3_ERRORS_PANIC 3 /* Panic */ > +#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE > + > +/* > + * Structure of the super block > + */ > +struct ext3_super_block { > +/*00*/ __le32 s_inodes_count; /* Inodes count */ > + __le32 s_blocks_count; /* Blocks count */ > + __le32 s_r_blocks_count; /* Reserved blocks count */ > + __le32 s_free_blocks_count; /* Free blocks count */ > +/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ > + __le32 s_first_data_block; /* First Data Block */ > + __le32 s_log_block_size; /* Block size */ > + __le32 s_log_frag_size; /* Fragment size */ > +/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ > + __le32 s_frags_per_group; /* # Fragments per group */ > + __le32 s_inodes_per_group; /* # Inodes per group */ > + __le32 s_mtime; /* Mount time */ > +/*30*/ __le32 s_wtime; /* Write time */ > + __le16 s_mnt_count; /* Mount count */ > + __le16 s_max_mnt_count; /* Maximal mount count */ > + __le16 s_magic; /* Magic signature */ > + __le16 s_state; /* File system state */ > + __le16 s_errors; /* Behaviour when detecting errors */ > + __le16 s_minor_rev_level; /* minor revision level */ > +/*40*/ __le32 s_lastcheck; /* time of last check */ > + __le32 s_checkinterval; /* max. time between checks */ > + __le32 s_creator_os; /* OS */ > + __le32 s_rev_level; /* Revision level */ > +/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ > + __le16 s_def_resgid; /* Default gid for reserved blocks */ > + /* > + * These fields are for EXT3_DYNAMIC_REV superblocks only. > + * > + * Note: the difference between the compatible feature set and > + * the incompatible feature set is that if there is a bit set > + * in the incompatible feature set that the kernel doesn't > + * know about, it should refuse to mount the filesystem. > + * > + * e2fsck's requirements are more strict; if it doesn't know > + * about a feature in either the compatible or incompatible > + * feature set, it must abort and not try to meddle with > + * things it doesn't understand... > + */ > + __le32 s_first_ino; /* First non-reserved inode */ > + __le16 s_inode_size; /* size of inode structure */ > + __le16 s_block_group_nr; /* block group # of this superblock */ > + __le32 s_feature_compat; /* compatible feature set */ > +/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ > + __le32 s_feature_ro_compat; /* readonly-compatible feature set */ > +/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ > +/*78*/ char s_volume_name[16]; /* volume name */ > +/*88*/ char s_last_mounted[64]; /* directory where last mounted */ > +/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ > + /* > + * Performance hints. Directory preallocation should only > + * happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on. > + */ > + __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ > + __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ > + __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ > + /* > + * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. > + */ > +/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ > +/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ > + __le32 s_journal_dev; /* device number of journal file */ > + __le32 s_last_orphan; /* start of list of inodes to delete */ > + __le32 s_hash_seed[4]; /* HTREE hash seed */ > + __u8 s_def_hash_version; /* Default hash version to use */ > + __u8 s_reserved_char_pad; > + __u16 s_reserved_word_pad; > + __le32 s_default_mount_opts; > + __le32 s_first_meta_bg; /* First metablock block group */ > + __le32 s_mkfs_time; /* When the filesystem was created */ > + __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ > + /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ > +/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ > + __le32 s_r_blocks_count_hi; /* Reserved blocks count */ > + __le32 s_free_blocks_count_hi; /* Free blocks count */ > + __le16 s_min_extra_isize; /* All inodes have at least # bytes */ > + __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ > + __le32 s_flags; /* Miscellaneous flags */ > + __le16 s_raid_stride; /* RAID stride */ > + __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ > + __le64 s_mmp_block; /* Block for multi-mount protection */ > + __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ > + __u8 s_log_groups_per_flex; /* FLEX_BG group size */ > + __u8 s_reserved_char_pad2; > + __le16 s_reserved_pad; > + __u32 s_reserved[162]; /* Padding to the end of the block */ > +}; > + > +/* data type for block offset of block group */ > +typedef int ext3_grpblk_t; > + > +/* data type for filesystem-wide blocks number */ > +typedef unsigned long ext3_fsblk_t; > + > +#define E3FSBLK "%lu" > + > +struct ext3_reserve_window { > + ext3_fsblk_t _rsv_start; /* First byte reserved */ > + ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ > +}; > + > +struct ext3_reserve_window_node { > + struct rb_node rsv_node; > + __u32 rsv_goal_size; > + __u32 rsv_alloc_hit; > + struct ext3_reserve_window rsv_window; > +}; > + > +struct ext3_block_alloc_info { > + /* information about reservation window */ > + struct ext3_reserve_window_node rsv_window_node; > + /* > + * was i_next_alloc_block in ext3_inode_info > + * is the logical (file-relative) number of the > + * most-recently-allocated block in this file. > + * We use this for detecting linearly ascending allocation requests. > + */ > + __u32 last_alloc_logical_block; > + /* > + * Was i_next_alloc_goal in ext3_inode_info > + * is the *physical* companion to i_next_alloc_block. > + * it the physical block number of the block which was most-recentl > + * allocated to this file. This give us the goal (target) for the next > + * allocation when we detect linearly ascending requests. > + */ > + ext3_fsblk_t last_alloc_physical_block; > +}; > + > +#define rsv_start rsv_window._rsv_start > +#define rsv_end rsv_window._rsv_end > + > +/* > + * third extended file system inode data in memory > + */ > +struct ext3_inode_info { > + __le32 i_data[15]; /* unconverted */ > + __u32 i_flags; > +#ifdef EXT3_FRAGMENTS > + __u32 i_faddr; > + __u8 i_frag_no; > + __u8 i_frag_size; > +#endif > + ext3_fsblk_t i_file_acl; > + __u32 i_dir_acl; > + __u32 i_dtime; > + > + /* > + * i_block_group is the number of the block group which contains > + * this file's inode. Constant across the lifetime of the inode, > + * it is ued for making block allocation decisions - we try to > + * place a file's data blocks near its inode block, and new inodes > + * near to their parent directory's inode. > + */ > + __u32 i_block_group; > + unsigned long i_state_flags; /* Dynamic state flags for ext3 */ > + > + /* block reservation info */ > + struct ext3_block_alloc_info *i_block_alloc_info; > + > + __u32 i_dir_start_lookup; > +#ifdef CONFIG_EXT3_FS_XATTR > + /* > + * Extended attributes can be read independently of the main file > + * data. Taking i_mutex even when reading would cause contention > + * between readers of EAs and writers of regular file data, so > + * instead we synchronize on xattr_sem when reading or changing > + * EAs. > + */ > + struct rw_semaphore xattr_sem; > +#endif > + > + struct list_head i_orphan; /* unlinked but open inodes */ > + > + /* > + * i_disksize keeps track of what the inode size is ON DISK, not > + * in memory. During truncate, i_size is set to the new size by > + * the VFS prior to calling ext3_truncate(), but the filesystem won't > + * set i_disksize to 0 until the truncate is actually under way. > + * > + * The intent is that i_disksize always represents the blocks which > + * are used by this file. This allows recovery to restart truncate > + * on orphans if we crash during truncate. We actually write i_disksize > + * into the on-disk inode when writing inodes out, instead of i_size. > + * > + * The only time when i_disksize and i_size may be different is when > + * a truncate is in progress. The only things which change i_disksize > + * are ext3_get_block (growth) and ext3_truncate (shrinkth). > + */ > + loff_t i_disksize; > + > + /* on-disk additional length */ > + __u16 i_extra_isize; > + > + /* > + * truncate_mutex is for serialising ext3_truncate() against > + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's > + * data tree are chopped off during truncate. We can't do that in > + * ext3 because whenever we perform intermediate commits during > + * truncate, the inode and all the metadata blocks *must* be in a > + * consistent state which allows truncation of the orphans to restart > + * during recovery. Hence we must fix the get_block-vs-truncate race > + * by other means, so we have truncate_mutex. > + */ > + struct mutex truncate_mutex; > + > + /* > + * Transactions that contain inode's metadata needed to complete > + * fsync and fdatasync, respectively. > + */ > + atomic_t i_sync_tid; > + atomic_t i_datasync_tid; > + > + struct inode vfs_inode; > +}; > + > +/* > + * third extended-fs super-block data in memory > + */ > +struct ext3_sb_info { > + unsigned long s_frag_size; /* Size of a fragment in bytes */ > + unsigned long s_frags_per_block;/* Number of fragments per block */ > + unsigned long s_inodes_per_block;/* Number of inodes per block */ > + unsigned long s_frags_per_group;/* Number of fragments in a group */ > + unsigned long s_blocks_per_group;/* Number of blocks in a group */ > + unsigned long s_inodes_per_group;/* Number of inodes in a group */ > + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ > + unsigned long s_gdb_count; /* Number of group descriptor blocks */ > + unsigned long s_desc_per_block; /* Number of group descriptors per block */ > + unsigned long s_groups_count; /* Number of groups in the fs */ > + unsigned long s_overhead_last; /* Last calculated overhead */ > + unsigned long s_blocks_last; /* Last seen block count */ > + struct buffer_head * s_sbh; /* Buffer containing the super block */ > + struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ > + struct buffer_head ** s_group_desc; > + unsigned long s_mount_opt; > + ext3_fsblk_t s_sb_block; > + uid_t s_resuid; > + gid_t s_resgid; > + unsigned short s_mount_state; > + unsigned short s_pad; > + int s_addr_per_block_bits; > + int s_desc_per_block_bits; > + int s_inode_size; > + int s_first_ino; > + spinlock_t s_next_gen_lock; > + u32 s_next_generation; > + u32 s_hash_seed[4]; > + int s_def_hash_version; > + int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ > + struct percpu_counter s_freeblocks_counter; > + struct percpu_counter s_freeinodes_counter; > + struct percpu_counter s_dirs_counter; > + struct blockgroup_lock *s_blockgroup_lock; > + > + /* root of the per fs reservation window tree */ > + spinlock_t s_rsv_window_lock; > + struct rb_root s_rsv_window_root; > + struct ext3_reserve_window_node s_rsv_window_head; > + > + /* Journaling */ > + struct inode * s_journal_inode; > + struct journal_s * s_journal; > + struct list_head s_orphan; > + struct mutex s_orphan_lock; > + struct mutex s_resize_lock; > + unsigned long s_commit_interval; > + struct block_device *journal_bdev; > +#ifdef CONFIG_QUOTA > + char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ > + int s_jquota_fmt; /* Format of quota to use */ > +#endif > +}; > + > +static inline spinlock_t * > +sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) > +{ > + return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); > +} > + > +static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) > +{ > + return sb->s_fs_info; > +} > +static inline struct ext3_inode_info *EXT3_I(struct inode *inode) > +{ > + return container_of(inode, struct ext3_inode_info, vfs_inode); > +} > + > +static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) > +{ > + return ino == EXT3_ROOT_INO || > + ino == EXT3_JOURNAL_INO || > + ino == EXT3_RESIZE_INO || > + (ino >= EXT3_FIRST_INO(sb) && > + ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); > +} > + > +/* > + * Inode dynamic state flags > + */ > +enum { > + EXT3_STATE_JDATA, /* journaled data exists */ > + EXT3_STATE_NEW, /* inode is newly created */ > + EXT3_STATE_XATTR, /* has in-inode xattrs */ > + EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ > +}; > + > +static inline int ext3_test_inode_state(struct inode *inode, int bit) > +{ > + return test_bit(bit, &EXT3_I(inode)->i_state_flags); > +} > + > +static inline void ext3_set_inode_state(struct inode *inode, int bit) > +{ > + set_bit(bit, &EXT3_I(inode)->i_state_flags); > +} > + > +static inline void ext3_clear_inode_state(struct inode *inode, int bit) > +{ > + clear_bit(bit, &EXT3_I(inode)->i_state_flags); > +} > + > +#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime > + > +/* > + * Codes for operating systems > + */ > +#define EXT3_OS_LINUX 0 > +#define EXT3_OS_HURD 1 > +#define EXT3_OS_MASIX 2 > +#define EXT3_OS_FREEBSD 3 > +#define EXT3_OS_LITES 4 > + > +/* > + * Revision levels > + */ > +#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */ > +#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ > + > +#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV > +#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV > + > +#define EXT3_GOOD_OLD_INODE_SIZE 128 > + > +/* > + * Feature set definitions > + */ > + > +#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \ > + ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) > +#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \ > + ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) > +#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \ > + ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) > +#define EXT3_SET_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) > +#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) > +#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) > +#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) > +#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) > +#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \ > + EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) > + > +#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001 > +#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002 > +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 > +#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008 > +#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010 > +#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020 > + > +#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 > +#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 > +#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 > + > +#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001 > +#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 > +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ > +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ > +#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 > + > +#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR > +#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ > + EXT3_FEATURE_INCOMPAT_RECOVER| \ > + EXT3_FEATURE_INCOMPAT_META_BG) > +#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ > + EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ > + EXT3_FEATURE_RO_COMPAT_BTREE_DIR) > + > +/* > + * Default values for user and/or group using reserved blocks > + */ > +#define EXT3_DEF_RESUID 0 > +#define EXT3_DEF_RESGID 0 > + > +/* > + * Default mount options > + */ > +#define EXT3_DEFM_DEBUG 0x0001 > +#define EXT3_DEFM_BSDGROUPS 0x0002 > +#define EXT3_DEFM_XATTR_USER 0x0004 > +#define EXT3_DEFM_ACL 0x0008 > +#define EXT3_DEFM_UID16 0x0010 > +#define EXT3_DEFM_JMODE 0x0060 > +#define EXT3_DEFM_JMODE_DATA 0x0020 > +#define EXT3_DEFM_JMODE_ORDERED 0x0040 > +#define EXT3_DEFM_JMODE_WBACK 0x0060 > + > +/* > + * Structure of a directory entry > + */ > +#define EXT3_NAME_LEN 255 > + > +struct ext3_dir_entry { > + __le32 inode; /* Inode number */ > + __le16 rec_len; /* Directory entry length */ > + __le16 name_len; /* Name length */ > + char name[EXT3_NAME_LEN]; /* File name */ > +}; > + > +/* > + * The new version of the directory entry. Since EXT3 structures are > + * stored in intel byte order, and the name_len field could never be > + * bigger than 255 chars, it's safe to reclaim the extra byte for the > + * file_type field. > + */ > +struct ext3_dir_entry_2 { > + __le32 inode; /* Inode number */ > + __le16 rec_len; /* Directory entry length */ > + __u8 name_len; /* Name length */ > + __u8 file_type; > + char name[EXT3_NAME_LEN]; /* File name */ > +}; > + > +/* > + * Ext3 directory file types. Only the low 3 bits are used. The > + * other bits are reserved for now. > + */ > +#define EXT3_FT_UNKNOWN 0 > +#define EXT3_FT_REG_FILE 1 > +#define EXT3_FT_DIR 2 > +#define EXT3_FT_CHRDEV 3 > +#define EXT3_FT_BLKDEV 4 > +#define EXT3_FT_FIFO 5 > +#define EXT3_FT_SOCK 6 > +#define EXT3_FT_SYMLINK 7 > + > +#define EXT3_FT_MAX 8 > + > +/* > + * EXT3_DIR_PAD defines the directory entries boundaries > + * > + * NOTE: It must be a multiple of 4 > + */ > +#define EXT3_DIR_PAD 4 > +#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) > +#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ > + ~EXT3_DIR_ROUND) > +#define EXT3_MAX_REC_LEN ((1<<16)-1) > + > +/* > + * Tests against MAX_REC_LEN etc were put in place for 64k block > + * sizes; if that is not possible on this arch, we can skip > + * those tests and speed things up. > + */ > +static inline unsigned ext3_rec_len_from_disk(__le16 dlen) > +{ > + unsigned len = le16_to_cpu(dlen); > + > +#if (PAGE_CACHE_SIZE >= 65536) > + if (len == EXT3_MAX_REC_LEN) > + return 1 << 16; > +#endif > + return len; > +} > + > +static inline __le16 ext3_rec_len_to_disk(unsigned len) > +{ > +#if (PAGE_CACHE_SIZE >= 65536) > + if (len == (1 << 16)) > + return cpu_to_le16(EXT3_MAX_REC_LEN); > + else if (len > (1 << 16)) > + BUG(); > +#endif > + return cpu_to_le16(len); > +} > + > +/* > + * Hash Tree Directory indexing > + * (c) Daniel Phillips, 2001 > + */ > + > +#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ > + EXT3_FEATURE_COMPAT_DIR_INDEX) && \ > + (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) > +#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) > +#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) > + > +/* Legal values for the dx_root hash_version field: */ > + > +#define DX_HASH_LEGACY 0 > +#define DX_HASH_HALF_MD4 1 > +#define DX_HASH_TEA 2 > +#define DX_HASH_LEGACY_UNSIGNED 3 > +#define DX_HASH_HALF_MD4_UNSIGNED 4 > +#define DX_HASH_TEA_UNSIGNED 5 > + > +/* hash info structure used by the directory hash */ > +struct dx_hash_info > +{ > + u32 hash; > + u32 minor_hash; > + int hash_version; > + u32 *seed; > +}; > + > +#define EXT3_HTREE_EOF 0x7fffffff > + > +/* > + * Control parameters used by ext3_htree_next_block > + */ > +#define HASH_NB_ALWAYS 1 > + > + > +/* > + * Describe an inode's exact location on disk and in memory > + */ > +struct ext3_iloc > +{ > + struct buffer_head *bh; > + unsigned long offset; > + unsigned long block_group; > +}; > + > +static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc) > +{ > + return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset); > +} > + > +/* > + * This structure is stuffed into the struct file's private_data field > + * for directories. It is where we put information so that we can do > + * readdir operations in hash tree order. > + */ > +struct dir_private_info { > + struct rb_root root; > + struct rb_node *curr_node; > + struct fname *extra_fname; > + loff_t last_pos; > + __u32 curr_hash; > + __u32 curr_minor_hash; > + __u32 next_hash; > +}; > + > +/* calculate the first block number of the group */ > +static inline ext3_fsblk_t > +ext3_group_first_block_no(struct super_block *sb, unsigned long group_no) > +{ > + return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) + > + le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); > +} > + > +/* > + * Special error return code only used by dx_probe() and its callers. > + */ > +#define ERR_BAD_DX_DIR -75000 > + > +/* > + * Function prototypes > + */ > + > +/* > + * Ok, these declarations are also in but none of the > + * ext3 source programs needs to include it so they are duplicated here. > + */ > +# define NORET_TYPE /**/ > +# define ATTRIB_NORET __attribute__((noreturn)) > +# define NORET_AND noreturn, > + > +/* balloc.c */ > +extern int ext3_bg_has_super(struct super_block *sb, int group); > +extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); > +extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode, > + ext3_fsblk_t goal, int *errp); > +extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode, > + ext3_fsblk_t goal, unsigned long *count, int *errp); > +extern void ext3_free_blocks (handle_t *handle, struct inode *inode, > + ext3_fsblk_t block, unsigned long count); > +extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb, > + ext3_fsblk_t block, unsigned long count, > + unsigned long *pdquot_freed_blocks); > +extern ext3_fsblk_t ext3_count_free_blocks (struct super_block *); > +extern void ext3_check_blocks_bitmap (struct super_block *); > +extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, > + unsigned int block_group, > + struct buffer_head ** bh); > +extern int ext3_should_retry_alloc(struct super_block *sb, int *retries); > +extern void ext3_init_block_alloc_info(struct inode *); > +extern void ext3_rsv_window_add(struct super_block *sb, struct ext3_reserve_window_node *rsv); > +extern int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range); > + > +/* dir.c */ > +extern int ext3_check_dir_entry(const char *, struct inode *, > + struct ext3_dir_entry_2 *, > + struct buffer_head *, unsigned long); > +extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, > + __u32 minor_hash, > + struct ext3_dir_entry_2 *dirent); > +extern void ext3_htree_free_dir_info(struct dir_private_info *p); > + > +/* fsync.c */ > +extern int ext3_sync_file(struct file *, loff_t, loff_t, int); > + > +/* hash.c */ > +extern int ext3fs_dirhash(const char *name, int len, struct > + dx_hash_info *hinfo); > + > +/* ialloc.c */ > +extern struct inode * ext3_new_inode (handle_t *, struct inode *, > + const struct qstr *, umode_t); > +extern void ext3_free_inode (handle_t *, struct inode *); > +extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); > +extern unsigned long ext3_count_free_inodes (struct super_block *); > +extern unsigned long ext3_count_dirs (struct super_block *); > +extern void ext3_check_inodes_bitmap (struct super_block *); > +extern unsigned long ext3_count_free (struct buffer_head *, unsigned); > + > + > +/* inode.c */ > +int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, > + struct buffer_head *bh, ext3_fsblk_t blocknr); > +struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); > +struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); > +int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, > + sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, > + int create); > + > +extern struct inode *ext3_iget(struct super_block *, unsigned long); > +extern int ext3_write_inode (struct inode *, struct writeback_control *); > +extern int ext3_setattr (struct dentry *, struct iattr *); > +extern void ext3_evict_inode (struct inode *); > +extern int ext3_sync_inode (handle_t *, struct inode *); > +extern void ext3_discard_reservation (struct inode *); > +extern void ext3_dirty_inode(struct inode *, int); > +extern int ext3_change_inode_journal_flag(struct inode *, int); > +extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); > +extern int ext3_can_truncate(struct inode *inode); > +extern void ext3_truncate(struct inode *inode); > +extern void ext3_set_inode_flags(struct inode *); > +extern void ext3_get_inode_flags(struct ext3_inode_info *); > +extern void ext3_set_aops(struct inode *inode); > +extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, > + u64 start, u64 len); > + > +/* ioctl.c */ > +extern long ext3_ioctl(struct file *, unsigned int, unsigned long); > +extern long ext3_compat_ioctl(struct file *, unsigned int, unsigned long); > + > +/* namei.c */ > +extern int ext3_orphan_add(handle_t *, struct inode *); > +extern int ext3_orphan_del(handle_t *, struct inode *); > +extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, > + __u32 start_minor_hash, __u32 *next_hash); > + > +/* resize.c */ > +extern int ext3_group_add(struct super_block *sb, > + struct ext3_new_group_data *input); > +extern int ext3_group_extend(struct super_block *sb, > + struct ext3_super_block *es, > + ext3_fsblk_t n_blocks_count); > + > +/* super.c */ > +extern __printf(3, 4) > +void ext3_error(struct super_block *, const char *, const char *, ...); > +extern void __ext3_std_error (struct super_block *, const char *, int); > +extern __printf(3, 4) > +void ext3_abort(struct super_block *, const char *, const char *, ...); > +extern __printf(3, 4) > +void ext3_warning(struct super_block *, const char *, const char *, ...); > +extern __printf(3, 4) > +void ext3_msg(struct super_block *, const char *, const char *, ...); > +extern void ext3_update_dynamic_rev (struct super_block *sb); > + > +#define ext3_std_error(sb, errno) \ > +do { \ > + if ((errno)) \ > + __ext3_std_error((sb), __func__, (errno)); \ > +} while (0) > + > +/* > + * Inodes and files operations > + */ > + > +/* dir.c */ > +extern const struct file_operations ext3_dir_operations; > + > +/* file.c */ > +extern const struct inode_operations ext3_file_inode_operations; > +extern const struct file_operations ext3_file_operations; > + > +/* namei.c */ > +extern const struct inode_operations ext3_dir_inode_operations; > +extern const struct inode_operations ext3_special_inode_operations; > + > +/* symlink.c */ > +extern const struct inode_operations ext3_symlink_inode_operations; > +extern const struct inode_operations ext3_fast_symlink_inode_operations; > + > +#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) > + > +/* Define the number of blocks we need to account to a transaction to > + * modify one block of data. > + * > + * We may have to touch one inode, one bitmap buffer, up to three > + * indirection blocks, the group and superblock summaries, and the data > + * block to complete the transaction. */ > + > +#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U > + > +/* Extended attribute operations touch at most two data buffers, > + * two bitmap buffers, and two group summaries, in addition to the inode > + * and the superblock, which are already accounted for. */ > + > +#define EXT3_XATTR_TRANS_BLOCKS 6U > + > +/* Define the minimum size for a transaction which modifies data. This > + * needs to take into account the fact that we may end up modifying two > + * quota files too (one for the group, one for the user quota). The > + * superblock only gets updated once, of course, so don't bother > + * counting that again for the quota updates. */ > + > +#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ > + EXT3_XATTR_TRANS_BLOCKS - 2 + \ > + EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) > + > +/* Delete operations potentially hit one directory's namespace plus an > + * entire inode, plus arbitrary amounts of bitmap/indirection data. Be > + * generous. We can grow the delete transaction later if necessary. */ > + > +#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) > + > +/* Define an arbitrary limit for the amount of data we will anticipate > + * writing to any given transaction. For unbounded transactions such as > + * write(2) and truncate(2) we can write more than this, but we always > + * start off at the maximum transaction size and grow the transaction > + * optimistically as we go. */ > + > +#define EXT3_MAX_TRANS_DATA 64U > + > +/* We break up a large truncate or write transaction once the handle's > + * buffer credits gets this low, we need either to extend the > + * transaction or to start a new one. Reserve enough space here for > + * inode, bitmap, superblock, group and indirection updates for at least > + * one block, plus two quota updates. Quota allocations are not > + * needed. */ > + > +#define EXT3_RESERVE_TRANS_BLOCKS 12U > + > +#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 > + > +#ifdef CONFIG_QUOTA > +/* Amount of blocks needed for quota update - we know that the structure was > + * allocated so we need to update only inode+data */ > +#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) > +/* Amount of blocks needed for quota insert/delete - we do some block writes > + * but inode, sb and group updates are done only once */ > +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ > + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) > +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ > + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) > +#else > +#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 > +#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 > +#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 > +#endif > +#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) > +#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) > +#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) > + > +int > +ext3_mark_iloc_dirty(handle_t *handle, > + struct inode *inode, > + struct ext3_iloc *iloc); > + > +/* > + * On success, We end up with an outstanding reference count against > + * iloc->bh. This _must_ be cleaned up later. > + */ > + > +int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, > + struct ext3_iloc *iloc); > + > +int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); > + > +/* > + * Wrapper functions with which ext3 calls into JBD. The intent here is > + * to allow these to be turned into appropriate stubs so ext3 can control > + * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't > + * been done yet. > + */ > + > +static inline void ext3_journal_release_buffer(handle_t *handle, > + struct buffer_head *bh) > +{ > + journal_release_buffer(handle, bh); > +} > + > +void ext3_journal_abort_handle(const char *caller, const char *err_fn, > + struct buffer_head *bh, handle_t *handle, int err); > + > +int __ext3_journal_get_undo_access(const char *where, handle_t *handle, > + struct buffer_head *bh); > + > +int __ext3_journal_get_write_access(const char *where, handle_t *handle, > + struct buffer_head *bh); > + > +int __ext3_journal_forget(const char *where, handle_t *handle, > + struct buffer_head *bh); > + > +int __ext3_journal_revoke(const char *where, handle_t *handle, > + unsigned long blocknr, struct buffer_head *bh); > + > +int __ext3_journal_get_create_access(const char *where, > + handle_t *handle, struct buffer_head *bh); > + > +int __ext3_journal_dirty_metadata(const char *where, > + handle_t *handle, struct buffer_head *bh); > + > +#define ext3_journal_get_undo_access(handle, bh) \ > + __ext3_journal_get_undo_access(__func__, (handle), (bh)) > +#define ext3_journal_get_write_access(handle, bh) \ > + __ext3_journal_get_write_access(__func__, (handle), (bh)) > +#define ext3_journal_revoke(handle, blocknr, bh) \ > + __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) > +#define ext3_journal_get_create_access(handle, bh) \ > + __ext3_journal_get_create_access(__func__, (handle), (bh)) > +#define ext3_journal_dirty_metadata(handle, bh) \ > + __ext3_journal_dirty_metadata(__func__, (handle), (bh)) > +#define ext3_journal_forget(handle, bh) \ > + __ext3_journal_forget(__func__, (handle), (bh)) > + > +int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); > + > +handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); > +int __ext3_journal_stop(const char *where, handle_t *handle); > + > +static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) > +{ > + return ext3_journal_start_sb(inode->i_sb, nblocks); > +} > + > +#define ext3_journal_stop(handle) \ > + __ext3_journal_stop(__func__, (handle)) > + > +static inline handle_t *ext3_journal_current_handle(void) > +{ > + return journal_current_handle(); > +} > + > +static inline int ext3_journal_extend(handle_t *handle, int nblocks) > +{ > + return journal_extend(handle, nblocks); > +} > + > +static inline int ext3_journal_restart(handle_t *handle, int nblocks) > +{ > + return journal_restart(handle, nblocks); > +} > + > +static inline int ext3_journal_blocks_per_page(struct inode *inode) > +{ > + return journal_blocks_per_page(inode); > +} > + > +static inline int ext3_journal_force_commit(journal_t *journal) > +{ > + return journal_force_commit(journal); > +} > + > +/* super.c */ > +int ext3_force_commit(struct super_block *sb); > + > +static inline int ext3_should_journal_data(struct inode *inode) > +{ > + if (!S_ISREG(inode->i_mode)) > + return 1; > + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) > + return 1; > + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > + return 1; > + return 0; > +} > + > +static inline int ext3_should_order_data(struct inode *inode) > +{ > + if (!S_ISREG(inode->i_mode)) > + return 0; > + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > + return 0; > + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) > + return 1; > + return 0; > +} > + > +static inline int ext3_should_writeback_data(struct inode *inode) > +{ > + if (!S_ISREG(inode->i_mode)) > + return 0; > + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > + return 0; > + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) > + return 1; > + return 0; > +} > + > +#include > + > diff --git a/instrumentation/events/mainline/gpio.h b/instrumentation/events/mainline/gpio.h > new file mode 100644 > index 0000000..927a8ad > --- /dev/null > +++ b/instrumentation/events/mainline/gpio.h > @@ -0,0 +1,56 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM gpio > + > +#if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_GPIO_H > + > +#include > + > +TRACE_EVENT(gpio_direction, > + > + TP_PROTO(unsigned gpio, int in, int err), > + > + TP_ARGS(gpio, in, err), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, in) > + __field(int, err) > + ), > + > + TP_fast_assign( > + __entry->gpio = gpio; > + __entry->in = in; > + __entry->err = err; > + ), > + > + TP_printk("%u %3s (%d)", __entry->gpio, > + __entry->in ? "in" : "out", __entry->err) > +); > + > +TRACE_EVENT(gpio_value, > + > + TP_PROTO(unsigned gpio, int get, int value), > + > + TP_ARGS(gpio, get, value), > + > + TP_STRUCT__entry( > + __field(unsigned, gpio) > + __field(int, get) > + __field(int, value) > + ), > + > + TP_fast_assign( > + __entry->gpio = gpio; > + __entry->get = get; > + __entry->value = value; > + ), > + > + TP_printk("%u %3s %d", __entry->gpio, > + __entry->get ? "get" : "set", __entry->value) > +); > + > +#endif /* if !defined(_TRACE_GPIO_H) || defined(TRACE_HEADER_MULTI_READ) */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/jbd.h b/instrumentation/events/mainline/jbd.h > new file mode 100644 > index 0000000..aff64d8 > --- /dev/null > +++ b/instrumentation/events/mainline/jbd.h > @@ -0,0 +1,203 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd > + > +#if !defined(_TRACE_JBD_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD_H > + > +#include > +#include > + > +TRACE_EVENT(jbd_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->result = result; > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->result) > +); > + > +DECLARE_EVENT_CLASS(jbd_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd_commit, jbd_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +TRACE_EVENT(jbd_drop_transaction, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +TRACE_EVENT(jbd_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + __entry->head = journal->j_tail_sequence; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +); > + > +TRACE_EVENT(jbd_do_submit_data, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +TRACE_EVENT(jbd_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->tail_sequence = journal->j_tail_sequence; > + __entry->first_tid = first_tid; > + __entry->block_nr = block_nr; > + __entry->freed = freed; > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +); > + > +TRACE_EVENT(jbd_update_superblock_end, > + TP_PROTO(journal_t *journal, int wait), > + > + TP_ARGS(journal, wait), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, wait ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->wait = wait; > + ), > + > + TP_printk("dev %d,%d wait %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->wait) > +); > + > +#endif /* _TRACE_JBD_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/jbd2.h b/instrumentation/events/mainline/jbd2.h > new file mode 100644 > index 0000000..7596441 > --- /dev/null > +++ b/instrumentation/events/mainline/jbd2.h > @@ -0,0 +1,235 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM jbd2 > + > +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_JBD2_H > + > +#include > +#include > + > +struct transaction_chp_stats_s; > +struct transaction_run_stats_s; > + > +TRACE_EVENT(jbd2_checkpoint, > + > + TP_PROTO(journal_t *journal, int result), > + > + TP_ARGS(journal, result), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, result ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->result = result; > + ), > + > + TP_printk("dev %d,%d result %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->result) > +); > + > +DECLARE_EVENT_CLASS(jbd2_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_start_commit, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_locking, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_flushing, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > +TRACE_EVENT(jbd2_end_commit, > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( char, sync_commit ) > + __field( int, transaction ) > + __field( int, head ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->sync_commit = commit_transaction->t_synchronous_commit; > + __entry->transaction = commit_transaction->t_tid; > + __entry->head = journal->j_tail_sequence; > + ), > + > + TP_printk("dev %d,%d transaction %d sync %d head %d", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->transaction, __entry->sync_commit, __entry->head) > +); > + > +TRACE_EVENT(jbd2_submit_inode_data, > + TP_PROTO(struct inode *inode), > + > + TP_ARGS(inode), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( ino_t, ino ) > + ), > + > + TP_fast_assign( > + __entry->dev = inode->i_sb->s_dev; > + __entry->ino = inode->i_ino; > + ), > + > + TP_printk("dev %d,%d ino %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + (unsigned long) __entry->ino) > +); > + > +TRACE_EVENT(jbd2_run_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_run_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, wait ) > + __field( unsigned long, running ) > + __field( unsigned long, locked ) > + __field( unsigned long, flushing ) > + __field( unsigned long, logging ) > + __field( __u32, handle_count ) > + __field( __u32, blocks ) > + __field( __u32, blocks_logged ) > + ), > + > + TP_fast_assign( > + __entry->dev = dev; > + __entry->tid = tid; > + __entry->wait = stats->rs_wait; > + __entry->running = stats->rs_running; > + __entry->locked = stats->rs_locked; > + __entry->flushing = stats->rs_flushing; > + __entry->logging = stats->rs_logging; > + __entry->handle_count = stats->rs_handle_count; > + __entry->blocks = stats->rs_blocks; > + __entry->blocks_logged = stats->rs_blocks_logged; > + ), > + > + TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " > + "logging %u handle_count %u blocks %u blocks_logged %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->wait), > + jiffies_to_msecs(__entry->running), > + jiffies_to_msecs(__entry->locked), > + jiffies_to_msecs(__entry->flushing), > + jiffies_to_msecs(__entry->logging), > + __entry->handle_count, __entry->blocks, > + __entry->blocks_logged) > +); > + > +TRACE_EVENT(jbd2_checkpoint_stats, > + TP_PROTO(dev_t dev, unsigned long tid, > + struct transaction_chp_stats_s *stats), > + > + TP_ARGS(dev, tid, stats), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( unsigned long, tid ) > + __field( unsigned long, chp_time ) > + __field( __u32, forced_to_close ) > + __field( __u32, written ) > + __field( __u32, dropped ) > + ), > + > + TP_fast_assign( > + __entry->dev = dev; > + __entry->tid = tid; > + __entry->chp_time = stats->cs_chp_time; > + __entry->forced_to_close= stats->cs_forced_to_close; > + __entry->written = stats->cs_written; > + __entry->dropped = stats->cs_dropped; > + ), > + > + TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " > + "written %u dropped %u", > + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, > + jiffies_to_msecs(__entry->chp_time), > + __entry->forced_to_close, __entry->written, __entry->dropped) > +); > + > +TRACE_EVENT(jbd2_cleanup_journal_tail, > + > + TP_PROTO(journal_t *journal, tid_t first_tid, > + unsigned long block_nr, unsigned long freed), > + > + TP_ARGS(journal, first_tid, block_nr, freed), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( tid_t, tail_sequence ) > + __field( tid_t, first_tid ) > + __field(unsigned long, block_nr ) > + __field(unsigned long, freed ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->tail_sequence = journal->j_tail_sequence; > + __entry->first_tid = first_tid; > + __entry->block_nr = block_nr; > + __entry->freed = freed; > + ), > + > + TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > + MAJOR(__entry->dev), MINOR(__entry->dev), > + __entry->tail_sequence, __entry->first_tid, > + __entry->block_nr, __entry->freed) > +); > + > +#endif /* _TRACE_JBD2_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/kmem.h b/instrumentation/events/mainline/kmem.h > new file mode 100644 > index 0000000..a9c87ad > --- /dev/null > +++ b/instrumentation/events/mainline/kmem.h > @@ -0,0 +1,308 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM kmem > + > +#if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_KMEM_H > + > +#include > +#include > +#include "gfpflags.h" > + > +DECLARE_EVENT_CLASS(kmem_alloc, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags)) > +); > + > +DEFINE_EVENT(kmem_alloc, kmalloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +); > + > +DEFINE_EVENT(kmem_alloc, kmem_cache_alloc, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, gfp_t gfp_flags), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags) > +); > + > +DECLARE_EVENT_CLASS(kmem_alloc_node, > + > + TP_PROTO(unsigned long call_site, > + const void *ptr, > + size_t bytes_req, > + size_t bytes_alloc, > + gfp_t gfp_flags, > + int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + __field( size_t, bytes_req ) > + __field( size_t, bytes_alloc ) > + __field( gfp_t, gfp_flags ) > + __field( int, node ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + __entry->bytes_req = bytes_req; > + __entry->bytes_alloc = bytes_alloc; > + __entry->gfp_flags = gfp_flags; > + __entry->node = node; > + ), > + > + TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", > + __entry->call_site, > + __entry->ptr, > + __entry->bytes_req, > + __entry->bytes_alloc, > + show_gfp_flags(__entry->gfp_flags), > + __entry->node) > +); > + > +DEFINE_EVENT(kmem_alloc_node, kmalloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +); > + > +DEFINE_EVENT(kmem_alloc_node, kmem_cache_alloc_node, > + > + TP_PROTO(unsigned long call_site, const void *ptr, > + size_t bytes_req, size_t bytes_alloc, > + gfp_t gfp_flags, int node), > + > + TP_ARGS(call_site, ptr, bytes_req, bytes_alloc, gfp_flags, node) > +); > + > +DECLARE_EVENT_CLASS(kmem_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr), > + > + TP_STRUCT__entry( > + __field( unsigned long, call_site ) > + __field( const void *, ptr ) > + ), > + > + TP_fast_assign( > + __entry->call_site = call_site; > + __entry->ptr = ptr; > + ), > + > + TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > +); > + > +DEFINE_EVENT(kmem_free, kfree, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +); > + > +DEFINE_EVENT(kmem_free, kmem_cache_free, > + > + TP_PROTO(unsigned long call_site, const void *ptr), > + > + TP_ARGS(call_site, ptr) > +); > + > +TRACE_EVENT(mm_page_free_direct, > + > + TP_PROTO(struct page *page, unsigned int order), > + > + TP_ARGS(page, order), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->order = order; > + ), > + > + TP_printk("page=%p pfn=%lu order=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order) > +); > + > +TRACE_EVENT(mm_pagevec_free, > + > + TP_PROTO(struct page *page, int cold), > + > + TP_ARGS(page, cold), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, cold ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->cold = cold; > + ), > + > + TP_printk("page=%p pfn=%lu order=0 cold=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->cold) > +); > + > +TRACE_EVENT(mm_page_alloc, > + > + TP_PROTO(struct page *page, unsigned int order, > + gfp_t gfp_flags, int migratetype), > + > + TP_ARGS(page, order, gfp_flags, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( gfp_t, gfp_flags ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->order = order; > + __entry->gfp_flags = gfp_flags; > + __entry->migratetype = migratetype; > + ), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + show_gfp_flags(__entry->gfp_flags)) > +); > + > +DECLARE_EVENT_CLASS(mm_page, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( unsigned int, order ) > + __field( int, migratetype ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->order = order; > + __entry->migratetype = migratetype; > + ), > + > + TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->order, > + __entry->migratetype, > + __entry->order == 0) > +); > + > +DEFINE_EVENT(mm_page, mm_page_alloc_zone_locked, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype) > +); > + > +DEFINE_EVENT_PRINT(mm_page, mm_page_pcpu_drain, > + > + TP_PROTO(struct page *page, unsigned int order, int migratetype), > + > + TP_ARGS(page, order, migratetype), > + > + TP_printk("page=%p pfn=%lu order=%d migratetype=%d", > + __entry->page, page_to_pfn(__entry->page), > + __entry->order, __entry->migratetype) > +); > + > +TRACE_EVENT(mm_page_alloc_extfrag, > + > + TP_PROTO(struct page *page, > + int alloc_order, int fallback_order, > + int alloc_migratetype, int fallback_migratetype), > + > + TP_ARGS(page, > + alloc_order, fallback_order, > + alloc_migratetype, fallback_migratetype), > + > + TP_STRUCT__entry( > + __field( struct page *, page ) > + __field( int, alloc_order ) > + __field( int, fallback_order ) > + __field( int, alloc_migratetype ) > + __field( int, fallback_migratetype ) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->alloc_order = alloc_order; > + __entry->fallback_order = fallback_order; > + __entry->alloc_migratetype = alloc_migratetype; > + __entry->fallback_migratetype = fallback_migratetype; > + ), > + > + TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", > + __entry->page, > + page_to_pfn(__entry->page), > + __entry->alloc_order, > + __entry->fallback_order, > + pageblock_order, > + __entry->alloc_migratetype, > + __entry->fallback_migratetype, > + __entry->fallback_order < pageblock_order, > + __entry->alloc_migratetype == __entry->fallback_migratetype) > +); > + > +#endif /* _TRACE_KMEM_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/lock.h b/instrumentation/events/mainline/lock.h > new file mode 100644 > index 0000000..2821b86 > --- /dev/null > +++ b/instrumentation/events/mainline/lock.h > @@ -0,0 +1,86 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM lock > + > +#if !defined(_TRACE_LOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_LOCK_H > + > +#include > +#include > + > +#ifdef CONFIG_LOCKDEP > + > +TRACE_EVENT(lock_acquire, > + > + TP_PROTO(struct lockdep_map *lock, unsigned int subclass, > + int trylock, int read, int check, > + struct lockdep_map *next_lock, unsigned long ip), > + > + TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip), > + > + TP_STRUCT__entry( > + __field(unsigned int, flags) > + __string(name, lock->name) > + __field(void *, lockdep_addr) > + ), > + > + TP_fast_assign( > + __entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0); > + __assign_str(name, lock->name); > + __entry->lockdep_addr = lock; > + ), > + > + TP_printk("%p %s%s%s", __entry->lockdep_addr, > + (__entry->flags & 1) ? "try " : "", > + (__entry->flags & 2) ? "read " : "", > + __get_str(name)) > +); > + > +DECLARE_EVENT_CLASS(lock, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip), > + > + TP_STRUCT__entry( > + __string( name, lock->name ) > + __field( void *, lockdep_addr ) > + ), > + > + TP_fast_assign( > + __assign_str(name, lock->name); > + __entry->lockdep_addr = lock; > + ), > + > + TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) > +); > + > +DEFINE_EVENT(lock, lock_release, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +); > + > +#ifdef CONFIG_LOCK_STAT > + > +DEFINE_EVENT(lock, lock_contended, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +); > + > +DEFINE_EVENT(lock, lock_acquired, > + > + TP_PROTO(struct lockdep_map *lock, unsigned long ip), > + > + TP_ARGS(lock, ip) > +); > + > +#endif > +#endif > + > +#endif /* _TRACE_LOCK_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/module.h b/instrumentation/events/mainline/module.h > new file mode 100644 > index 0000000..21a546d > --- /dev/null > +++ b/instrumentation/events/mainline/module.h > @@ -0,0 +1,131 @@ > +/* > + * Because linux/module.h has tracepoints in the header, and ftrace.h > + * eventually includes this file, define_trace.h includes linux/module.h > + * But we do not want the module.h to override the TRACE_SYSTEM macro > + * variable that define_trace.h is processing, so we only set it > + * when module events are being processed, which would happen when > + * CREATE_TRACE_POINTS is defined. > + */ > +#ifdef CREATE_TRACE_POINTS > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM module > +#endif > + > +#if !defined(_TRACE_MODULE_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_MODULE_H > + > +#include > + > +#ifdef CONFIG_MODULES > + > +struct module; > + > +#define show_module_flags(flags) __print_flags(flags, "", \ > + { (1UL << TAINT_PROPRIETARY_MODULE), "P" }, \ > + { (1UL << TAINT_FORCED_MODULE), "F" }, \ > + { (1UL << TAINT_CRAP), "C" }) > + > +TRACE_EVENT(module_load, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __field( unsigned int, taints ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + __entry->taints = mod->taints; > + __assign_str(name, mod->name); > + ), > + > + TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) > +); > + > +TRACE_EVENT(module_free, > + > + TP_PROTO(struct module *mod), > + > + TP_ARGS(mod), > + > + TP_STRUCT__entry( > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, mod->name); > + ), > + > + TP_printk("%s", __get_str(name)) > +); > + > +#ifdef CONFIG_MODULE_UNLOAD > +/* trace_module_get/put are only used if CONFIG_MODULE_UNLOAD is defined */ > + > +DECLARE_EVENT_CLASS(module_refcnt, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( int, refcnt ) > + __string( name, mod->name ) > + ), > + > + TP_fast_assign( > + __entry->ip = ip; > + __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs); > + __assign_str(name, mod->name); > + ), > + > + TP_printk("%s call_site=%pf refcnt=%d", > + __get_str(name), (void *)__entry->ip, __entry->refcnt) > +); > + > +DEFINE_EVENT(module_refcnt, module_get, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +); > + > +DEFINE_EVENT(module_refcnt, module_put, > + > + TP_PROTO(struct module *mod, unsigned long ip), > + > + TP_ARGS(mod, ip) > +); > +#endif /* CONFIG_MODULE_UNLOAD */ > + > +TRACE_EVENT(module_request, > + > + TP_PROTO(char *name, bool wait, unsigned long ip), > + > + TP_ARGS(name, wait, ip), > + > + TP_STRUCT__entry( > + __field( unsigned long, ip ) > + __field( bool, wait ) > + __string( name, name ) > + ), > + > + TP_fast_assign( > + __entry->ip = ip; > + __entry->wait = wait; > + __assign_str(name, name); > + ), > + > + TP_printk("%s wait=%d call_site=%pf", > + __get_str(name), (int)__entry->wait, (void *)__entry->ip) > +); > + > +#endif /* CONFIG_MODULES */ > + > +#endif /* _TRACE_MODULE_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/napi.h b/instrumentation/events/mainline/napi.h > new file mode 100644 > index 0000000..8fe1e93 > --- /dev/null > +++ b/instrumentation/events/mainline/napi.h > @@ -0,0 +1,38 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM napi > + > +#if !defined(_TRACE_NAPI_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NAPI_H_ > + > +#include > +#include > +#include > + > +#define NO_DEV "(no_device)" > + > +TRACE_EVENT(napi_poll, > + > + TP_PROTO(struct napi_struct *napi), > + > + TP_ARGS(napi), > + > + TP_STRUCT__entry( > + __field( struct napi_struct *, napi) > + __string( dev_name, napi->dev ? napi->dev->name : NO_DEV) > + ), > + > + TP_fast_assign( > + __entry->napi = napi; > + __assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV); > + ), > + > + TP_printk("napi poll on napi struct %p for device %s", > + __entry->napi, __get_str(dev_name)) > +); > + > +#undef NO_DEV > + > +#endif /* _TRACE_NAPI_H_ */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/net.h b/instrumentation/events/mainline/net.h > new file mode 100644 > index 0000000..f99645d > --- /dev/null > +++ b/instrumentation/events/mainline/net.h > @@ -0,0 +1,84 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM net > + > +#if !defined(_TRACE_NET_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_NET_H > + > +#include > +#include > +#include > +#include > + > +TRACE_EVENT(net_dev_xmit, > + > + TP_PROTO(struct sk_buff *skb, > + int rc, > + struct net_device *dev, > + unsigned int skb_len), > + > + TP_ARGS(skb, rc, dev, skb_len), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __field( int, rc ) > + __string( name, dev->name ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->len = skb_len; > + __entry->rc = rc; > + __assign_str(name, dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u rc=%d", > + __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) > +); > + > +DECLARE_EVENT_CLASS(net_dev_template, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( unsigned int, len ) > + __string( name, skb->dev->name ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->len = skb->len; > + __assign_str(name, skb->dev->name); > + ), > + > + TP_printk("dev=%s skbaddr=%p len=%u", > + __get_str(name), __entry->skbaddr, __entry->len) > +) > + > +DEFINE_EVENT(net_dev_template, net_dev_queue, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +); > + > +DEFINE_EVENT(net_dev_template, netif_receive_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +); > + > +DEFINE_EVENT(net_dev_template, netif_rx, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb) > +); > +#endif /* _TRACE_NET_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/power.h b/instrumentation/events/mainline/power.h > new file mode 100644 > index 0000000..1bcc2a8 > --- /dev/null > +++ b/instrumentation/events/mainline/power.h > @@ -0,0 +1,240 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM power > + > +#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_POWER_H > + > +#include > +#include > + > +DECLARE_EVENT_CLASS(cpu, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + __field( u32, cpu_id ) > + ), > + > + TP_fast_assign( > + __entry->state = state; > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, > + (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(cpu, cpu_idle, > + > + TP_PROTO(unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(state, cpu_id) > +); > + > +/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING > + > +#define PWR_EVENT_EXIT -1 > +#endif > + > +DEFINE_EVENT(cpu, cpu_frequency, > + > + TP_PROTO(unsigned int frequency, unsigned int cpu_id), > + > + TP_ARGS(frequency, cpu_id) > +); > + > +TRACE_EVENT(machine_suspend, > + > + TP_PROTO(unsigned int state), > + > + TP_ARGS(state), > + > + TP_STRUCT__entry( > + __field( u32, state ) > + ), > + > + TP_fast_assign( > + __entry->state = state; > + ), > + > + TP_printk("state=%lu", (unsigned long)__entry->state) > +); > + > +/* This code will be removed after deprecation time exceeded (2.6.41) */ > +#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED > + > +/* > + * The power events are used for cpuidle & suspend (power_start, power_end) > + * and for cpufreq (power_frequency) > + */ > +DECLARE_EVENT_CLASS(power, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, type ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __entry->type = type; > + __entry->state = state; > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(power, power_start, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +); > + > +DEFINE_EVENT(power, power_frequency, > + > + TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(type, state, cpu_id) > +); > + > +TRACE_EVENT(power_end, > + > + TP_PROTO(unsigned int cpu_id), > + > + TP_ARGS(cpu_id), > + > + TP_STRUCT__entry( > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) > + > +); > + > +/* Deprecated dummy functions must be protected against multi-declartion */ > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > + > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED > +enum { > + POWER_NONE = 0, > + POWER_CSTATE = 1, > + POWER_PSTATE = 2, > +}; > + > +/* These dummy declaration have to be ripped out when the deprecated > + events get removed */ > +static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; > +static inline void trace_power_end(u64 cpuid) {}; > +static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; > +#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > + > +#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */ > + > +/* > + * The clock events are used for clock enable/disable and for > + * clock rate change > + */ > +DECLARE_EVENT_CLASS(clock, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->state = state; > + __entry->cpu_id = cpu_id; > + ), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(clock, clock_enable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > + > +DEFINE_EVENT(clock, clock_disable, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > + > +DEFINE_EVENT(clock, clock_set_rate, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > + > +/* > + * The power domain events are used for power domains transitions > + */ > +DECLARE_EVENT_CLASS(power_domain, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + __field( u64, cpu_id ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->state = state; > + __entry->cpu_id = cpu_id; > +), > + > + TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > + (unsigned long)__entry->state, (unsigned long)__entry->cpu_id) > +); > + > +DEFINE_EVENT(power_domain, power_domain_target, > + > + TP_PROTO(const char *name, unsigned int state, unsigned int cpu_id), > + > + TP_ARGS(name, state, cpu_id) > +); > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/regulator.h b/instrumentation/events/mainline/regulator.h > new file mode 100644 > index 0000000..37502a7 > --- /dev/null > +++ b/instrumentation/events/mainline/regulator.h > @@ -0,0 +1,141 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM regulator > + > +#if !defined(_TRACE_REGULATOR_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_REGULATOR_H > + > +#include > +#include > + > +/* > + * Events which just log themselves and the regulator name for enable/disable > + * type tracking. > + */ > +DECLARE_EVENT_CLASS(regulator_basic, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name), > + > + TP_STRUCT__entry( > + __string( name, name ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + ), > + > + TP_printk("name=%s", __get_str(name)) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_enable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_enable_delay, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_enable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_disable, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +DEFINE_EVENT(regulator_basic, regulator_disable_complete, > + > + TP_PROTO(const char *name), > + > + TP_ARGS(name) > + > +); > + > +/* > + * Events that take a range of numerical values, mostly for voltages > + * and so on. > + */ > +DECLARE_EVENT_CLASS(regulator_range, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( int, min ) > + __field( int, max ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->min = min; > + __entry->max = max; > + ), > + > + TP_printk("name=%s (%d-%d)", __get_str(name), > + (int)__entry->min, (int)__entry->max) > +); > + > +DEFINE_EVENT(regulator_range, regulator_set_voltage, > + > + TP_PROTO(const char *name, int min, int max), > + > + TP_ARGS(name, min, max) > + > +); > + > + > +/* > + * Events that take a single value, mostly for readback and refcounts. > + */ > +DECLARE_EVENT_CLASS(regulator_value, > + > + TP_PROTO(const char *name, unsigned int val), > + > + TP_ARGS(name, val), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( unsigned int, val ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->val = val; > + ), > + > + TP_printk("name=%s, val=%u", __get_str(name), > + (int)__entry->val) > +); > + > +DEFINE_EVENT(regulator_value, regulator_set_voltage_complete, > + > + TP_PROTO(const char *name, unsigned int value), > + > + TP_ARGS(name, value) > + > +); > + > +#endif /* _TRACE_POWER_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/scsi.h b/instrumentation/events/mainline/scsi.h > new file mode 100644 > index 0000000..db6c935 > --- /dev/null > +++ b/instrumentation/events/mainline/scsi.h > @@ -0,0 +1,365 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM scsi > + > +#if !defined(_TRACE_SCSI_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SCSI_H > + > +#include > +#include > +#include > +#include > + > +#define scsi_opcode_name(opcode) { opcode, #opcode } > +#define show_opcode_name(val) \ > + __print_symbolic(val, \ > + scsi_opcode_name(TEST_UNIT_READY), \ > + scsi_opcode_name(REZERO_UNIT), \ > + scsi_opcode_name(REQUEST_SENSE), \ > + scsi_opcode_name(FORMAT_UNIT), \ > + scsi_opcode_name(READ_BLOCK_LIMITS), \ > + scsi_opcode_name(REASSIGN_BLOCKS), \ > + scsi_opcode_name(INITIALIZE_ELEMENT_STATUS), \ > + scsi_opcode_name(READ_6), \ > + scsi_opcode_name(WRITE_6), \ > + scsi_opcode_name(SEEK_6), \ > + scsi_opcode_name(READ_REVERSE), \ > + scsi_opcode_name(WRITE_FILEMARKS), \ > + scsi_opcode_name(SPACE), \ > + scsi_opcode_name(INQUIRY), \ > + scsi_opcode_name(RECOVER_BUFFERED_DATA), \ > + scsi_opcode_name(MODE_SELECT), \ > + scsi_opcode_name(RESERVE), \ > + scsi_opcode_name(RELEASE), \ > + scsi_opcode_name(COPY), \ > + scsi_opcode_name(ERASE), \ > + scsi_opcode_name(MODE_SENSE), \ > + scsi_opcode_name(START_STOP), \ > + scsi_opcode_name(RECEIVE_DIAGNOSTIC), \ > + scsi_opcode_name(SEND_DIAGNOSTIC), \ > + scsi_opcode_name(ALLOW_MEDIUM_REMOVAL), \ > + scsi_opcode_name(SET_WINDOW), \ > + scsi_opcode_name(READ_CAPACITY), \ > + scsi_opcode_name(READ_10), \ > + scsi_opcode_name(WRITE_10), \ > + scsi_opcode_name(SEEK_10), \ > + scsi_opcode_name(POSITION_TO_ELEMENT), \ > + scsi_opcode_name(WRITE_VERIFY), \ > + scsi_opcode_name(VERIFY), \ > + scsi_opcode_name(SEARCH_HIGH), \ > + scsi_opcode_name(SEARCH_EQUAL), \ > + scsi_opcode_name(SEARCH_LOW), \ > + scsi_opcode_name(SET_LIMITS), \ > + scsi_opcode_name(PRE_FETCH), \ > + scsi_opcode_name(READ_POSITION), \ > + scsi_opcode_name(SYNCHRONIZE_CACHE), \ > + scsi_opcode_name(LOCK_UNLOCK_CACHE), \ > + scsi_opcode_name(READ_DEFECT_DATA), \ > + scsi_opcode_name(MEDIUM_SCAN), \ > + scsi_opcode_name(COMPARE), \ > + scsi_opcode_name(COPY_VERIFY), \ > + scsi_opcode_name(WRITE_BUFFER), \ > + scsi_opcode_name(READ_BUFFER), \ > + scsi_opcode_name(UPDATE_BLOCK), \ > + scsi_opcode_name(READ_LONG), \ > + scsi_opcode_name(WRITE_LONG), \ > + scsi_opcode_name(CHANGE_DEFINITION), \ > + scsi_opcode_name(WRITE_SAME), \ > + scsi_opcode_name(UNMAP), \ > + scsi_opcode_name(READ_TOC), \ > + scsi_opcode_name(LOG_SELECT), \ > + scsi_opcode_name(LOG_SENSE), \ > + scsi_opcode_name(XDWRITEREAD_10), \ > + scsi_opcode_name(MODE_SELECT_10), \ > + scsi_opcode_name(RESERVE_10), \ > + scsi_opcode_name(RELEASE_10), \ > + scsi_opcode_name(MODE_SENSE_10), \ > + scsi_opcode_name(PERSISTENT_RESERVE_IN), \ > + scsi_opcode_name(PERSISTENT_RESERVE_OUT), \ > + scsi_opcode_name(VARIABLE_LENGTH_CMD), \ > + scsi_opcode_name(REPORT_LUNS), \ > + scsi_opcode_name(MAINTENANCE_IN), \ > + scsi_opcode_name(MAINTENANCE_OUT), \ > + scsi_opcode_name(MOVE_MEDIUM), \ > + scsi_opcode_name(EXCHANGE_MEDIUM), \ > + scsi_opcode_name(READ_12), \ > + scsi_opcode_name(WRITE_12), \ > + scsi_opcode_name(WRITE_VERIFY_12), \ > + scsi_opcode_name(SEARCH_HIGH_12), \ > + scsi_opcode_name(SEARCH_EQUAL_12), \ > + scsi_opcode_name(SEARCH_LOW_12), \ > + scsi_opcode_name(READ_ELEMENT_STATUS), \ > + scsi_opcode_name(SEND_VOLUME_TAG), \ > + scsi_opcode_name(WRITE_LONG_2), \ > + scsi_opcode_name(READ_16), \ > + scsi_opcode_name(WRITE_16), \ > + scsi_opcode_name(VERIFY_16), \ > + scsi_opcode_name(WRITE_SAME_16), \ > + scsi_opcode_name(SERVICE_ACTION_IN), \ > + scsi_opcode_name(SAI_READ_CAPACITY_16), \ > + scsi_opcode_name(SAI_GET_LBA_STATUS), \ > + scsi_opcode_name(MI_REPORT_TARGET_PGS), \ > + scsi_opcode_name(MO_SET_TARGET_PGS), \ > + scsi_opcode_name(READ_32), \ > + scsi_opcode_name(WRITE_32), \ > + scsi_opcode_name(WRITE_SAME_32), \ > + scsi_opcode_name(ATA_16), \ > + scsi_opcode_name(ATA_12)) > + > +#define scsi_hostbyte_name(result) { result, #result } > +#define show_hostbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_hostbyte_name(DID_OK), \ > + scsi_hostbyte_name(DID_NO_CONNECT), \ > + scsi_hostbyte_name(DID_BUS_BUSY), \ > + scsi_hostbyte_name(DID_TIME_OUT), \ > + scsi_hostbyte_name(DID_BAD_TARGET), \ > + scsi_hostbyte_name(DID_ABORT), \ > + scsi_hostbyte_name(DID_PARITY), \ > + scsi_hostbyte_name(DID_ERROR), \ > + scsi_hostbyte_name(DID_RESET), \ > + scsi_hostbyte_name(DID_BAD_INTR), \ > + scsi_hostbyte_name(DID_PASSTHROUGH), \ > + scsi_hostbyte_name(DID_SOFT_ERROR), \ > + scsi_hostbyte_name(DID_IMM_RETRY), \ > + scsi_hostbyte_name(DID_REQUEUE), \ > + scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ > + scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) > + > +#define scsi_driverbyte_name(result) { result, #result } > +#define show_driverbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_driverbyte_name(DRIVER_OK), \ > + scsi_driverbyte_name(DRIVER_BUSY), \ > + scsi_driverbyte_name(DRIVER_SOFT), \ > + scsi_driverbyte_name(DRIVER_MEDIA), \ > + scsi_driverbyte_name(DRIVER_ERROR), \ > + scsi_driverbyte_name(DRIVER_INVALID), \ > + scsi_driverbyte_name(DRIVER_TIMEOUT), \ > + scsi_driverbyte_name(DRIVER_HARD), \ > + scsi_driverbyte_name(DRIVER_SENSE)) > + > +#define scsi_msgbyte_name(result) { result, #result } > +#define show_msgbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_msgbyte_name(COMMAND_COMPLETE), \ > + scsi_msgbyte_name(EXTENDED_MESSAGE), \ > + scsi_msgbyte_name(SAVE_POINTERS), \ > + scsi_msgbyte_name(RESTORE_POINTERS), \ > + scsi_msgbyte_name(DISCONNECT), \ > + scsi_msgbyte_name(INITIATOR_ERROR), \ > + scsi_msgbyte_name(ABORT_TASK_SET), \ > + scsi_msgbyte_name(MESSAGE_REJECT), \ > + scsi_msgbyte_name(NOP), \ > + scsi_msgbyte_name(MSG_PARITY_ERROR), \ > + scsi_msgbyte_name(LINKED_CMD_COMPLETE), \ > + scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \ > + scsi_msgbyte_name(TARGET_RESET), \ > + scsi_msgbyte_name(ABORT_TASK), \ > + scsi_msgbyte_name(CLEAR_TASK_SET), \ > + scsi_msgbyte_name(INITIATE_RECOVERY), \ > + scsi_msgbyte_name(RELEASE_RECOVERY), \ > + scsi_msgbyte_name(CLEAR_ACA), \ > + scsi_msgbyte_name(LOGICAL_UNIT_RESET), \ > + scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \ > + scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \ > + scsi_msgbyte_name(ORDERED_QUEUE_TAG), \ > + scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \ > + scsi_msgbyte_name(ACA), \ > + scsi_msgbyte_name(QAS_REQUEST), \ > + scsi_msgbyte_name(BUS_DEVICE_RESET), \ > + scsi_msgbyte_name(ABORT)) > + > +#define scsi_statusbyte_name(result) { result, #result } > +#define show_statusbyte_name(val) \ > + __print_symbolic(val, \ > + scsi_statusbyte_name(SAM_STAT_GOOD), \ > + scsi_statusbyte_name(SAM_STAT_CHECK_CONDITION), \ > + scsi_statusbyte_name(SAM_STAT_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_BUSY), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE), \ > + scsi_statusbyte_name(SAM_STAT_INTERMEDIATE_CONDITION_MET), \ > + scsi_statusbyte_name(SAM_STAT_RESERVATION_CONFLICT), \ > + scsi_statusbyte_name(SAM_STAT_COMMAND_TERMINATED), \ > + scsi_statusbyte_name(SAM_STAT_TASK_SET_FULL), \ > + scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ > + scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) > + > +#define scsi_prot_op_name(result) { result, #result } > +#define show_prot_op_name(val) \ > + __print_symbolic(val, \ > + scsi_prot_op_name(SCSI_PROT_NORMAL), \ > + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ > + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ > + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) > + > +const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); > +#define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) > + > +TRACE_EVENT(scsi_dispatch_cmd_start, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + __entry->host_no = cmd->device->host->host_no; > + __entry->channel = cmd->device->channel; > + __entry->id = cmd->device->id; > + __entry->lun = cmd->device->lun; > + __entry->opcode = cmd->cmnd[0]; > + __entry->cmd_len = cmd->cmd_len; > + __entry->data_sglen = scsi_sg_count(cmd); > + __entry->prot_sglen = scsi_prot_sg_count(cmd); > + __entry->prot_op = scsi_get_prot_op(cmd); > + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) > +); > + > +TRACE_EVENT(scsi_dispatch_cmd_error, > + > + TP_PROTO(struct scsi_cmnd *cmd, int rtn), > + > + TP_ARGS(cmd, rtn), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, rtn ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + __entry->host_no = cmd->device->host->host_no; > + __entry->channel = cmd->device->channel; > + __entry->id = cmd->device->id; > + __entry->lun = cmd->device->lun; > + __entry->rtn = rtn; > + __entry->opcode = cmd->cmnd[0]; > + __entry->cmd_len = cmd->cmd_len; > + __entry->data_sglen = scsi_sg_count(cmd); > + __entry->prot_sglen = scsi_prot_sg_count(cmd); > + __entry->prot_op = scsi_get_prot_op(cmd); > + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + __entry->rtn) > +); > + > +DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > + > + TP_PROTO(struct scsi_cmnd *cmd), > + > + TP_ARGS(cmd), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + __field( unsigned int, channel ) > + __field( unsigned int, id ) > + __field( unsigned int, lun ) > + __field( int, result ) > + __field( unsigned int, opcode ) > + __field( unsigned int, cmd_len ) > + __field( unsigned int, data_sglen ) > + __field( unsigned int, prot_sglen ) > + __field( unsigned char, prot_op ) > + __dynamic_array(unsigned char, cmnd, cmd->cmd_len) > + ), > + > + TP_fast_assign( > + __entry->host_no = cmd->device->host->host_no; > + __entry->channel = cmd->device->channel; > + __entry->id = cmd->device->id; > + __entry->lun = cmd->device->lun; > + __entry->result = cmd->result; > + __entry->opcode = cmd->cmnd[0]; > + __entry->cmd_len = cmd->cmd_len; > + __entry->data_sglen = scsi_sg_count(cmd); > + __entry->prot_sglen = scsi_prot_sg_count(cmd); > + __entry->prot_op = scsi_get_prot_op(cmd); > + memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); > + ), > + > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ > + "%s host=%s message=%s status=%s)", > + __entry->host_no, __entry->channel, __entry->id, > + __entry->lun, __entry->data_sglen, __entry->prot_sglen, > + show_prot_op_name(__entry->prot_op), > + show_opcode_name(__entry->opcode), > + __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > + __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > + show_driverbyte_name(((__entry->result) >> 24) & 0xff), > + show_hostbyte_name(((__entry->result) >> 16) & 0xff), > + show_msgbyte_name(((__entry->result) >> 8) & 0xff), > + show_statusbyte_name(__entry->result & 0xff)) > +); > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_done, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)); > + > +DEFINE_EVENT(scsi_cmd_done_timeout_template, scsi_dispatch_cmd_timeout, > + TP_PROTO(struct scsi_cmnd *cmd), > + TP_ARGS(cmd)); > + > +TRACE_EVENT(scsi_eh_wakeup, > + > + TP_PROTO(struct Scsi_Host *shost), > + > + TP_ARGS(shost), > + > + TP_STRUCT__entry( > + __field( unsigned int, host_no ) > + ), > + > + TP_fast_assign( > + __entry->host_no = shost->host_no; > + ), > + > + TP_printk("host_no=%u", __entry->host_no) > +); > + > +#endif /* _TRACE_SCSI_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/skb.h b/instrumentation/events/mainline/skb.h > new file mode 100644 > index 0000000..0c68ae2 > --- /dev/null > +++ b/instrumentation/events/mainline/skb.h > @@ -0,0 +1,75 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM skb > + > +#if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SKB_H > + > +#include > +#include > +#include > + > +/* > + * Tracepoint for free an sk_buff: > + */ > +TRACE_EVENT(kfree_skb, > + > + TP_PROTO(struct sk_buff *skb, void *location), > + > + TP_ARGS(skb, location), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + __field( void *, location ) > + __field( unsigned short, protocol ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->location = location; > + __entry->protocol = ntohs(skb->protocol); > + ), > + > + TP_printk("skbaddr=%p protocol=%u location=%p", > + __entry->skbaddr, __entry->protocol, __entry->location) > +); > + > +TRACE_EVENT(consume_skb, > + > + TP_PROTO(struct sk_buff *skb), > + > + TP_ARGS(skb), > + > + TP_STRUCT__entry( > + __field( void *, skbaddr ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + ), > + > + TP_printk("skbaddr=%p", __entry->skbaddr) > +); > + > +TRACE_EVENT(skb_copy_datagram_iovec, > + > + TP_PROTO(const struct sk_buff *skb, int len), > + > + TP_ARGS(skb, len), > + > + TP_STRUCT__entry( > + __field( const void *, skbaddr ) > + __field( int, len ) > + ), > + > + TP_fast_assign( > + __entry->skbaddr = skb; > + __entry->len = len; > + ), > + > + TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) > +); > + > +#endif /* _TRACE_SKB_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/sock.h b/instrumentation/events/mainline/sock.h > new file mode 100644 > index 0000000..779abb9 > --- /dev/null > +++ b/instrumentation/events/mainline/sock.h > @@ -0,0 +1,68 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM sock > + > +#if !defined(_TRACE_SOCK_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_SOCK_H > + > +#include > +#include > + > +TRACE_EVENT(sock_rcvqueue_full, > + > + TP_PROTO(struct sock *sk, struct sk_buff *skb), > + > + TP_ARGS(sk, skb), > + > + TP_STRUCT__entry( > + __field(int, rmem_alloc) > + __field(unsigned int, truesize) > + __field(int, sk_rcvbuf) > + ), > + > + TP_fast_assign( > + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); > + __entry->truesize = skb->truesize; > + __entry->sk_rcvbuf = sk->sk_rcvbuf; > + ), > + > + TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", > + __entry->rmem_alloc, __entry->truesize, __entry->sk_rcvbuf) > +); > + > +TRACE_EVENT(sock_exceed_buf_limit, > + > + TP_PROTO(struct sock *sk, struct proto *prot, long allocated), > + > + TP_ARGS(sk, prot, allocated), > + > + TP_STRUCT__entry( > + __array(char, name, 32) > + __field(long *, sysctl_mem) > + __field(long, allocated) > + __field(int, sysctl_rmem) > + __field(int, rmem_alloc) > + ), > + > + TP_fast_assign( > + strncpy(__entry->name, prot->name, 32); > + __entry->sysctl_mem = prot->sysctl_mem; > + __entry->allocated = allocated; > + __entry->sysctl_rmem = prot->sysctl_rmem[0]; > + __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); > + ), > + > + TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " > + "sysctl_rmem=%d rmem_alloc=%d", > + __entry->name, > + __entry->sysctl_mem[0], > + __entry->sysctl_mem[1], > + __entry->sysctl_mem[2], > + __entry->allocated, > + __entry->sysctl_rmem, > + __entry->rmem_alloc) > +); > + > +#endif /* _TRACE_SOCK_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/udp.h b/instrumentation/events/mainline/udp.h > new file mode 100644 > index 0000000..a664bb9 > --- /dev/null > +++ b/instrumentation/events/mainline/udp.h > @@ -0,0 +1,32 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM udp > + > +#if !defined(_TRACE_UDP_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_UDP_H > + > +#include > +#include > + > +TRACE_EVENT(udp_fail_queue_rcv_skb, > + > + TP_PROTO(int rc, struct sock *sk), > + > + TP_ARGS(rc, sk), > + > + TP_STRUCT__entry( > + __field(int, rc) > + __field(__u16, lport) > + ), > + > + TP_fast_assign( > + __entry->rc = rc; > + __entry->lport = inet_sk(sk)->inet_num; > + ), > + > + TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) > +); > + > +#endif /* _TRACE_UDP_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/instrumentation/events/mainline/vmscan.h b/instrumentation/events/mainline/vmscan.h > new file mode 100644 > index 0000000..36851f7 > --- /dev/null > +++ b/instrumentation/events/mainline/vmscan.h > @@ -0,0 +1,477 @@ > +#undef TRACE_SYSTEM > +#define TRACE_SYSTEM vmscan > + > +#if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) > +#define _TRACE_VMSCAN_H > + > +#include > +#include > +#include > +#include > +#include "gfpflags.h" > + > +#define RECLAIM_WB_ANON 0x0001u > +#define RECLAIM_WB_FILE 0x0002u > +#define RECLAIM_WB_MIXED 0x0010u > +#define RECLAIM_WB_SYNC 0x0004u > +#define RECLAIM_WB_ASYNC 0x0008u > + > +#define show_reclaim_flags(flags) \ > + (flags) ? __print_flags(flags, "|", \ > + {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ > + {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ > + {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ > + {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ > + {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ > + ) : "RECLAIM_WB_NONE" > + > +#define trace_reclaim_flags(page, sync) ( \ > + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + ) > + > +#define trace_shrink_flags(file, sync) ( \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ > + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + ) > + > +TRACE_EVENT(mm_vmscan_kswapd_sleep, > + > + TP_PROTO(int nid), > + > + TP_ARGS(nid), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + ), > + > + TP_printk("nid=%d", __entry->nid) > +); > + > +TRACE_EVENT(mm_vmscan_kswapd_wake, > + > + TP_PROTO(int nid, int order), > + > + TP_ARGS(nid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + __entry->order = order; > + ), > + > + TP_printk("nid=%d order=%d", __entry->nid, __entry->order) > +); > + > +TRACE_EVENT(mm_vmscan_wakeup_kswapd, > + > + TP_PROTO(int nid, int zid, int order), > + > + TP_ARGS(nid, zid, order), > + > + TP_STRUCT__entry( > + __field( int, nid ) > + __field( int, zid ) > + __field( int, order ) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + __entry->zid = zid; > + __entry->order = order; > + ), > + > + TP_printk("nid=%d zid=%d order=%d", > + __entry->nid, > + __entry->zid, > + __entry->order) > +); > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags), > + > + TP_STRUCT__entry( > + __field( int, order ) > + __field( int, may_writepage ) > + __field( gfp_t, gfp_flags ) > + ), > + > + TP_fast_assign( > + __entry->order = order; > + __entry->may_writepage = may_writepage; > + __entry->gfp_flags = gfp_flags; > + ), > + > + TP_printk("order=%d may_writepage=%d gfp_flags=%s", > + __entry->order, > + __entry->may_writepage, > + show_gfp_flags(__entry->gfp_flags)) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, > + > + TP_PROTO(int order, int may_writepage, gfp_t gfp_flags), > + > + TP_ARGS(order, may_writepage, gfp_flags) > +); > + > +DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed), > + > + TP_STRUCT__entry( > + __field( unsigned long, nr_reclaimed ) > + ), > + > + TP_fast_assign( > + __entry->nr_reclaimed = nr_reclaimed; > + ), > + > + TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_direct_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +); > + > +DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, > + > + TP_PROTO(unsigned long nr_reclaimed), > + > + TP_ARGS(nr_reclaimed) > +); > + > +TRACE_EVENT(mm_shrink_slab_start, > + TP_PROTO(struct shrinker *shr, struct shrink_control *sc, > + long nr_objects_to_shrink, unsigned long pgs_scanned, > + unsigned long lru_pgs, unsigned long cache_items, > + unsigned long long delta, unsigned long total_scan), > + > + TP_ARGS(shr, sc, nr_objects_to_shrink, pgs_scanned, lru_pgs, > + cache_items, delta, total_scan), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, nr_objects_to_shrink) > + __field(gfp_t, gfp_flags) > + __field(unsigned long, pgs_scanned) > + __field(unsigned long, lru_pgs) > + __field(unsigned long, cache_items) > + __field(unsigned long long, delta) > + __field(unsigned long, total_scan) > + ), > + > + TP_fast_assign( > + __entry->shr = shr; > + __entry->shrink = shr->shrink; > + __entry->nr_objects_to_shrink = nr_objects_to_shrink; > + __entry->gfp_flags = sc->gfp_mask; > + __entry->pgs_scanned = pgs_scanned; > + __entry->lru_pgs = lru_pgs; > + __entry->cache_items = cache_items; > + __entry->delta = delta; > + __entry->total_scan = total_scan; > + ), > + > + TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", > + __entry->shrink, > + __entry->shr, > + __entry->nr_objects_to_shrink, > + show_gfp_flags(__entry->gfp_flags), > + __entry->pgs_scanned, > + __entry->lru_pgs, > + __entry->cache_items, > + __entry->delta, > + __entry->total_scan) > +); > + > +TRACE_EVENT(mm_shrink_slab_end, > + TP_PROTO(struct shrinker *shr, int shrinker_retval, > + long unused_scan_cnt, long new_scan_cnt), > + > + TP_ARGS(shr, shrinker_retval, unused_scan_cnt, new_scan_cnt), > + > + TP_STRUCT__entry( > + __field(struct shrinker *, shr) > + __field(void *, shrink) > + __field(long, unused_scan) > + __field(long, new_scan) > + __field(int, retval) > + __field(long, total_scan) > + ), > + > + TP_fast_assign( > + __entry->shr = shr; > + __entry->shrink = shr->shrink; > + __entry->unused_scan = unused_scan_cnt; > + __entry->new_scan = new_scan_cnt; > + __entry->retval = shrinker_retval; > + __entry->total_scan = new_scan_cnt - unused_scan_cnt; > + ), > + > + TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", > + __entry->shrink, > + __entry->shr, > + __entry->unused_scan, > + __entry->new_scan, > + __entry->total_scan, > + __entry->retval) > +); > + > +DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > + int isolate_mode), > + > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), > + > + TP_STRUCT__entry( > + __field(int, order) > + __field(unsigned long, nr_requested) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_taken) > + __field(unsigned long, nr_lumpy_taken) > + __field(unsigned long, nr_lumpy_dirty) > + __field(unsigned long, nr_lumpy_failed) > + __field(int, isolate_mode) > + ), > + > + TP_fast_assign( > + __entry->order = order; > + __entry->nr_requested = nr_requested; > + __entry->nr_scanned = nr_scanned; > + __entry->nr_taken = nr_taken; > + __entry->nr_lumpy_taken = nr_lumpy_taken; > + __entry->nr_lumpy_dirty = nr_lumpy_dirty; > + __entry->nr_lumpy_failed = nr_lumpy_failed; > + __entry->isolate_mode = isolate_mode; > + ), > + > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", > + __entry->isolate_mode, > + __entry->order, > + __entry->nr_requested, > + __entry->nr_scanned, > + __entry->nr_taken, > + __entry->nr_lumpy_taken, > + __entry->nr_lumpy_dirty, > + __entry->nr_lumpy_failed) > +); > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > + int isolate_mode), > + > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > + > +); > + > +DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, > + > + TP_PROTO(int order, > + unsigned long nr_requested, > + unsigned long nr_scanned, > + unsigned long nr_taken, > + unsigned long nr_lumpy_taken, > + unsigned long nr_lumpy_dirty, > + unsigned long nr_lumpy_failed, > + int isolate_mode), > + > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > + > +); > + > +TRACE_EVENT(mm_vmscan_writepage, > + > + TP_PROTO(struct page *page, > + int reclaim_flags), > + > + TP_ARGS(page, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(struct page *, page) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + __entry->page = page; > + __entry->reclaim_flags = reclaim_flags; > + ), > + > + TP_printk("page=%p pfn=%lu flags=%s", > + __entry->page, > + page_to_pfn(__entry->page), > + show_reclaim_flags(__entry->reclaim_flags)) > +); > + > +TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > + > + TP_PROTO(int nid, int zid, > + unsigned long nr_scanned, unsigned long nr_reclaimed, > + int priority, int reclaim_flags), > + > + TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), > + > + TP_STRUCT__entry( > + __field(int, nid) > + __field(int, zid) > + __field(unsigned long, nr_scanned) > + __field(unsigned long, nr_reclaimed) > + __field(int, priority) > + __field(int, reclaim_flags) > + ), > + > + TP_fast_assign( > + __entry->nid = nid; > + __entry->zid = zid; > + __entry->nr_scanned = nr_scanned; > + __entry->nr_reclaimed = nr_reclaimed; > + __entry->priority = priority; > + __entry->reclaim_flags = reclaim_flags; > + ), > + > + TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", > + __entry->nid, __entry->zid, > + __entry->nr_scanned, __entry->nr_reclaimed, > + __entry->priority, > + show_reclaim_flags(__entry->reclaim_flags)) > +); > + > +TRACE_EVENT(replace_swap_token, > + TP_PROTO(struct mm_struct *old_mm, > + struct mm_struct *new_mm), > + > + TP_ARGS(old_mm, new_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, old_mm) > + __field(unsigned int, old_prio) > + __field(struct mm_struct*, new_mm) > + __field(unsigned int, new_prio) > + ), > + > + TP_fast_assign( > + __entry->old_mm = old_mm; > + __entry->old_prio = old_mm ? old_mm->token_priority : 0; > + __entry->new_mm = new_mm; > + __entry->new_prio = new_mm->token_priority; > + ), > + > + TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", > + __entry->old_mm, __entry->old_prio, > + __entry->new_mm, __entry->new_prio) > +); > + > +DECLARE_EVENT_CLASS(put_swap_token_template, > + TP_PROTO(struct mm_struct *swap_token_mm), > + > + TP_ARGS(swap_token_mm), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, swap_token_mm) > + ), > + > + TP_fast_assign( > + __entry->swap_token_mm = swap_token_mm; > + ), > + > + TP_printk("token_mm=%p", __entry->swap_token_mm) > +); > + > +DEFINE_EVENT(put_swap_token_template, put_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm) > +); > + > +DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, > + TP_PROTO(struct mm_struct *swap_token_mm), > + TP_ARGS(swap_token_mm), > + TP_CONDITION(swap_token_mm != NULL) > +); > + > +TRACE_EVENT_CONDITION(update_swap_token_priority, > + TP_PROTO(struct mm_struct *mm, > + unsigned int old_prio, > + struct mm_struct *swap_token_mm), > + > + TP_ARGS(mm, old_prio, swap_token_mm), > + > + TP_CONDITION(mm->token_priority != old_prio), > + > + TP_STRUCT__entry( > + __field(struct mm_struct*, mm) > + __field(unsigned int, old_prio) > + __field(unsigned int, new_prio) > + __field(struct mm_struct*, swap_token_mm) > + __field(unsigned int, swap_token_prio) > + ), > + > + TP_fast_assign( > + __entry->mm = mm; > + __entry->old_prio = old_prio; > + __entry->new_prio = mm->token_priority; > + __entry->swap_token_mm = swap_token_mm; > + __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0; > + ), > + > + TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", > + __entry->mm, __entry->old_prio, __entry->new_prio, > + __entry->swap_token_mm, __entry->swap_token_prio) > +); > + > +#endif /* _TRACE_VMSCAN_H */ > + > +/* This part must be outside protection */ > +#include > diff --git a/probes/Makefile b/probes/Makefile > index 6efd6ad..c39a84a 100644 > --- a/probes/Makefile > +++ b/probes/Makefile > @@ -12,6 +12,9 @@ obj-m += lttng-probe-lttng.o > obj-m += lttng-probe-sched.o > obj-m += lttng-probe-irq.o > obj-m += lttng-probe-timer.o > +obj-m += lttng-probe-kmem.o > +obj-m += lttng-probe-module.o > +obj-m += lttng-probe-power.o > > obj-m += lttng-probe-statedump.o > > @@ -33,6 +36,75 @@ obj-m += $(shell \ > endif > endif > > +ifneq ($(CONFIG_NET),) > +obj-m += lttng-probe-net.o > +obj-m += lttng-probe-napi.o > +obj-m += lttng-probe-skb.o > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-sock.o" ; fi;) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-udp.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_SND_SOC),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ > + echo "lttng-probe-asoc.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_EXT3_FS),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-ext3.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_GPIOLIB),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 ] ; then \ > + echo "lttng-probe-gpio.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_JBD2),) > +obj-m += lttng-probe-jbd2.o > +endif > + > +ifneq ($(CONFIG_JBD),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > + echo "lttng-probe-jbd.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_REGULATOR),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ > + echo "lttng-probe-regulator.o" ; fi;) > +endif > + > +ifneq ($(CONFIG_SCSI),) > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 ] ; then \ > + echo "lttng-probe-scsi.o" ; fi;) > +endif > + > +vmscan = $(shell \ > + if [ $(VERSION) -ge 3 ] ; then \ > + echo "lttng-probe-vmscan.o" ; fi;) > +ifneq ($(CONFIG_SWAP),) > + obj-m += $(vmscan) > +else > +ifneq ($(CONFIG_CGROUP_MEM_RES_CTLR),) > + obj-m += $(vmscan) > +endif > +endif > + > +ifneq ($(CONFIG_LOCKDEP),) > +obj-m += lttng-probe-lock.o > +endif > + > ifneq ($(CONFIG_KPROBES),) > obj-m += lttng-kprobes.o > endif > diff --git a/probes/lttng-probe-asoc.c b/probes/lttng-probe-asoc.c > new file mode 100644 > index 0000000..427639f > --- /dev/null > +++ b/probes/lttng-probe-asoc.c > @@ -0,0 +1,45 @@ > +/* > + * probes/lttng-probe-block.c > + * > + * LTTng asoc probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/asoc.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng asoc probes"); > diff --git a/probes/lttng-probe-ext3.c b/probes/lttng-probe-ext3.c > new file mode 100644 > index 0000000..0df2b67 > --- /dev/null > +++ b/probes/lttng-probe-ext3.c > @@ -0,0 +1,56 @@ > +/* > + * probes/lttng-probe-ext3.c > + * > + * LTTng ext3 probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > +#include > +#include > + > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > +/* > + * Since 3.4 the is no linux/ext3_fs_i.h anymore. Instead we have to use > + * ext3.h from fs/ext3/ext3.h (which also includes trace/events/ext3.h) > + */ > +#include "../instrumentation/events/mainline/fs_ext3.h" > +#else > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > +#endif > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/ext3.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng ext3 probes"); > diff --git a/probes/lttng-probe-gpio.c b/probes/lttng-probe-gpio.c > new file mode 100644 > index 0000000..51692a7 > --- /dev/null > +++ b/probes/lttng-probe-gpio.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-gpio.c > + * > + * LTTng gpio probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/gpio.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng gpio probes"); > diff --git a/probes/lttng-probe-jbd.c b/probes/lttng-probe-jbd.c > new file mode 100644 > index 0000000..46911cc > --- /dev/null > +++ b/probes/lttng-probe-jbd.c > @@ -0,0 +1,44 @@ > +/* > + * probes/lttng-probe-jbd.c > + * > + * LTTng jbd probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/jbd.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng jbd probes"); > diff --git a/probes/lttng-probe-jbd2.c b/probes/lttng-probe-jbd2.c > new file mode 100644 > index 0000000..eea0a66 > --- /dev/null > +++ b/probes/lttng-probe-jbd2.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-jbd2.c > + * > + * LTTng jbd2 probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/jbd2.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng jbd2 probes"); > diff --git a/probes/lttng-probe-kmem.c b/probes/lttng-probe-kmem.c > new file mode 100644 > index 0000000..af67759 > --- /dev/null > +++ b/probes/lttng-probe-kmem.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-kmem.c > + * > + * LTTng kmem probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/kmem.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng kmem probes"); > diff --git a/probes/lttng-probe-lock.c b/probes/lttng-probe-lock.c > new file mode 100644 > index 0000000..16ac0e7 > --- /dev/null > +++ b/probes/lttng-probe-lock.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-lock.c > + * > + * LTTng lock probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/lock.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng lock probes"); > diff --git a/probes/lttng-probe-module.c b/probes/lttng-probe-module.c > new file mode 100644 > index 0000000..1a3c255 > --- /dev/null > +++ b/probes/lttng-probe-module.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-module.c > + * > + * LTTng module probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/module.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng module probes"); > diff --git a/probes/lttng-probe-napi.c b/probes/lttng-probe-napi.c > new file mode 100644 > index 0000000..cae8504 > --- /dev/null > +++ b/probes/lttng-probe-napi.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-napi.c > + * > + * LTTng napi probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/napi.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng napi probes"); > diff --git a/probes/lttng-probe-net.c b/probes/lttng-probe-net.c > new file mode 100644 > index 0000000..54212be > --- /dev/null > +++ b/probes/lttng-probe-net.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-net.c > + * > + * LTTng net probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/net.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng net probes"); > diff --git a/probes/lttng-probe-power.c b/probes/lttng-probe-power.c > new file mode 100644 > index 0000000..5dcb93f > --- /dev/null > +++ b/probes/lttng-probe-power.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-power.c > + * > + * LTTng power probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/power.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng power probes"); > diff --git a/probes/lttng-probe-regulator.c b/probes/lttng-probe-regulator.c > new file mode 100644 > index 0000000..7c8b7f9 > --- /dev/null > +++ b/probes/lttng-probe-regulator.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-regulator.c > + * > + * LTTng regulator probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/regulator.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng regulator probes"); > diff --git a/probes/lttng-probe-scsi.c b/probes/lttng-probe-scsi.c > new file mode 100644 > index 0000000..51702c3 > --- /dev/null > +++ b/probes/lttng-probe-scsi.c > @@ -0,0 +1,44 @@ > +/* > + * probes/lttng-probe-scsi.c > + * > + * LTTng scsi probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/scsi.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng scsi probes"); > diff --git a/probes/lttng-probe-skb.c b/probes/lttng-probe-skb.c > new file mode 100644 > index 0000000..52edf88 > --- /dev/null > +++ b/probes/lttng-probe-skb.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-skb.c > + * > + * LTTng skb probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/skb.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng skb probes"); > diff --git a/probes/lttng-probe-sock.c b/probes/lttng-probe-sock.c > new file mode 100644 > index 0000000..b3e699a > --- /dev/null > +++ b/probes/lttng-probe-sock.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-sock.c > + * > + * LTTng sock probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/sock.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng sock probes"); > diff --git a/probes/lttng-probe-udp.c b/probes/lttng-probe-udp.c > new file mode 100644 > index 0000000..51ec3cb > --- /dev/null > +++ b/probes/lttng-probe-udp.c > @@ -0,0 +1,43 @@ > +/* > + * probes/lttng-probe-udp.c > + * > + * LTTng udp probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#include "../instrumentation/events/lttng-module/udp.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth "); > +MODULE_DESCRIPTION("LTTng udp probes"); > diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c > new file mode 100644 > index 0000000..2abd0e4 > --- /dev/null > +++ b/probes/lttng-probe-vmscan.c > @@ -0,0 +1,48 @@ > +/* > + * probes/lttng-probe-vmscan.c > + * > + * LTTng vmscan probes. > + * > + * Copyright (C) 2010-2012 Mathieu Desnoyers > + * Copyright (C) 2012 Mentor Graphics Corp. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > +#include > + > +/* > + * Create the tracepoint static inlines from the kernel to validate that our > + * trace event macros match the kernel we run on. > + */ > +#include > + > +/* > + * Create LTTng tracepoint probes. > + */ > +#define LTTNG_PACKAGE_BUILD > +#define CREATE_TRACE_POINTS > +#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) > +typedef int isolate_mode_t; > +#endif > + > +#include "../instrumentation/events/lttng-module/vmscan.h" > + > +MODULE_LICENSE("GPL and additional rights"); > +MODULE_AUTHOR("Wade Farnsworth and Paul Woegerer "); > +MODULE_DESCRIPTION("LTTng vmscan probes"); > -- > 1.7.10.4 > > > From 5b1d2fa2044ba95020a12671da188fbe85967c80 Mon Sep 17 00:00:00 2001 > From: Paul Woegerer > Date: Tue, 13 Nov 2012 16:58:22 +0100 > Subject: [PATCH 2/3] Add ifdefs to net probe to support Linux 2.6.39 > > --- > instrumentation/events/lttng-module/net.h | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > > diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h > index c25b0d9..589011c 100644 > --- a/instrumentation/events/lttng-module/net.h > +++ b/instrumentation/events/lttng-module/net.h > @@ -8,29 +8,50 @@ > #include > #include > #include > +#include > > TRACE_EVENT(net_dev_xmit, > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > TP_PROTO(struct sk_buff *skb, > int rc, > struct net_device *dev, > unsigned int skb_len), > > TP_ARGS(skb, rc, dev, skb_len), > +#else > + TP_PROTO(struct sk_buff *skb, > + int rc), > + > + TP_ARGS(skb, rc), > +#endif > > TP_STRUCT__entry( > __field( void *, skbaddr ) > __field( unsigned int, len ) > __field( int, rc ) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > __string( name, dev->name ) > +#else > + __string( name, skb->dev->name ) > +#endif > ), > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > TP_fast_assign( > tp_assign(skbaddr, skb); > tp_assign(len, skb_len); > tp_assign(rc, rc); > tp_strcpy(name, dev->name); > ), > +#else > + TP_fast_assign( > + tp_assign(skbaddr, skb); > + tp_assign(len, skb->len); > + tp_assign(rc, rc); > + tp_strcpy(name, skb->dev->name); > + ), > +#endif > > TP_printk("dev=%s skbaddr=%p len=%u rc=%d", > __get_str(name), __entry->skbaddr, __entry->len, __entry->rc) > -- > 1.7.10.4 > > > From 0f2be20124423c54865f9e45f035c75b8e7a5598 Mon Sep 17 00:00:00 2001 > From: Paul Woegerer > Date: Wed, 14 Nov 2012 10:10:49 +0100 > Subject: [PATCH 3/3] Remove semicolons in TP_fast_assign blocks. > > --- > instrumentation/events/lttng-module/asoc.h | 54 ++--- > instrumentation/events/lttng-module/ext3.h | 238 +++++++++++------------ > instrumentation/events/lttng-module/gpio.h | 12 +- > instrumentation/events/lttng-module/jbd.h | 44 ++--- > instrumentation/events/lttng-module/jbd2.h | 42 ++-- > instrumentation/events/lttng-module/kmem.h | 58 +++--- > instrumentation/events/lttng-module/lock.h | 10 +- > instrumentation/events/lttng-module/module.h | 18 +- > instrumentation/events/lttng-module/napi.h | 4 +- > instrumentation/events/lttng-module/net.h | 22 +-- > instrumentation/events/lttng-module/power.h | 26 +-- > instrumentation/events/lttng-module/regulator.h | 12 +- > instrumentation/events/lttng-module/scsi.h | 66 +++---- > instrumentation/events/lttng-module/skb.h | 12 +- > instrumentation/events/lttng-module/sock.h | 14 +- > instrumentation/events/lttng-module/udp.h | 4 +- > instrumentation/events/lttng-module/vmscan.h | 104 +++++----- > 17 files changed, 370 insertions(+), 370 deletions(-) > > diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h > index cb9e701..6ffc923 100644 > --- a/instrumentation/events/lttng-module/asoc.h > +++ b/instrumentation/events/lttng-module/asoc.h > @@ -37,10 +37,10 @@ DECLARE_EVENT_CLASS(snd_soc_reg, > ), > > TP_fast_assign( > - tp_strcpy(name, codec->name); > - tp_assign(id, codec->id); > - tp_assign(reg, reg); > - tp_assign(val, val); > + tp_strcpy(name, codec->name) > + tp_assign(id, codec->id) > + tp_assign(reg, reg) > + tp_assign(val, val) > ), > > TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), > @@ -82,10 +82,10 @@ DECLARE_EVENT_CLASS(snd_soc_preg, > ), > > TP_fast_assign( > - tp_strcpy(name, platform->name); > - tp_assign(id, platform->id); > - tp_assign(reg, reg); > - tp_assign(val, val); > + tp_strcpy(name, platform->name) > + tp_assign(id, platform->id) > + tp_assign(reg, reg) > + tp_assign(val, val) > ), > > TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), > @@ -124,8 +124,8 @@ DECLARE_EVENT_CLASS(snd_soc_card, > ), > > TP_fast_assign( > - tp_strcpy(name, card->name); > - tp_assign(val, val); > + tp_strcpy(name, card->name) > + tp_assign(val, val) > ), > > TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) > @@ -158,7 +158,7 @@ DECLARE_EVENT_CLASS(snd_soc_dapm_basic, > ), > > TP_fast_assign( > - tp_strcpy(name, card->name); > + tp_strcpy(name, card->name) > ), > > TP_printk("card=%s", __get_str(name)) > @@ -192,8 +192,8 @@ DECLARE_EVENT_CLASS(snd_soc_dapm_widget, > ), > > TP_fast_assign( > - tp_strcpy(name, w->name); > - tp_assign(val, val); > + tp_strcpy(name, w->name) > + tp_assign(val, val) > ), > > TP_printk("widget=%s val=%d", __get_str(name), > @@ -239,10 +239,10 @@ TRACE_EVENT(snd_soc_dapm_walk_done, > ), > > TP_fast_assign( > - tp_strcpy(name, card->name); > - tp_assign(power_checks, card->dapm_stats.power_checks); > - tp_assign(path_checks, card->dapm_stats.path_checks); > - tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks); > + tp_strcpy(name, card->name) > + tp_assign(power_checks, card->dapm_stats.power_checks) > + tp_assign(path_checks, card->dapm_stats.path_checks) > + tp_assign(neighbour_checks, card->dapm_stats.neighbour_checks) > ), > > TP_printk("%s: checks %d power, %d path, %d neighbour", > @@ -262,7 +262,7 @@ TRACE_EVENT(snd_soc_jack_irq, > ), > > TP_fast_assign( > - tp_strcpy(name, name); > + tp_strcpy(name, name) > ), > > TP_printk("%s", __get_str(name)) > @@ -281,9 +281,9 @@ TRACE_EVENT(snd_soc_jack_report, > ), > > TP_fast_assign( > - tp_strcpy(name, jack->jack->name); > - tp_assign(mask, mask); > - tp_assign(val, val); > + tp_strcpy(name, jack->jack->name) > + tp_assign(mask, mask) > + tp_assign(val, val) > ), > > TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, > @@ -302,8 +302,8 @@ TRACE_EVENT(snd_soc_jack_notify, > ), > > TP_fast_assign( > - tp_strcpy(name, jack->jack->name); > - tp_assign(val, val); > + tp_strcpy(name, jack->jack->name) > + tp_assign(val, val) > ), > > TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) > @@ -324,10 +324,10 @@ TRACE_EVENT(snd_soc_cache_sync, > ), > > TP_fast_assign( > - tp_strcpy(name, codec->name); > - tp_strcpy(status, status); > - tp_strcpy(type, type); > - tp_assign(id, codec->id); > + tp_strcpy(name, codec->name) > + tp_strcpy(status, status) > + tp_strcpy(type, type) > + tp_assign(id, codec->id) > ), > > TP_printk("codec=%s.%d type=%s status=%s", __get_str(name), > diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h > index e02ecf4..de80df9 100644 > --- a/instrumentation/events/lttng-module/ext3.h > +++ b/instrumentation/events/lttng-module/ext3.h > @@ -27,12 +27,12 @@ TRACE_EVENT(ext3_free_inode, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(mode, inode->i_mode); > - tp_assign(uid, inode->i_uid); > - tp_assign(gid, inode->i_gid); > - tp_assign(blocks, inode->i_blocks); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(mode, inode->i_mode) > + tp_assign(uid, inode->i_uid) > + tp_assign(gid, inode->i_gid) > + tp_assign(blocks, inode->i_blocks) > ), > > TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %lu", > @@ -54,9 +54,9 @@ TRACE_EVENT(ext3_request_inode, > ), > > TP_fast_assign( > - tp_assign(dev, dir->i_sb->s_dev); > - tp_assign(dir, dir->i_ino); > - tp_assign(mode, mode); > + tp_assign(dev, dir->i_sb->s_dev) > + tp_assign(dir, dir->i_ino) > + tp_assign(mode, mode) > ), > > TP_printk("dev %d,%d dir %lu mode 0%o", > @@ -77,10 +77,10 @@ TRACE_EVENT(ext3_allocate_inode, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(dir, dir->i_ino); > - tp_assign(mode, mode); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(dir, dir->i_ino) > + tp_assign(mode, mode) > ), > > TP_printk("dev %d,%d ino %lu dir %lu mode 0%o", > @@ -101,9 +101,9 @@ TRACE_EVENT(ext3_evict_inode, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(nlink, inode->i_nlink); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(nlink, inode->i_nlink) > ), > > TP_printk("dev %d,%d ino %lu nlink %d", > @@ -123,9 +123,9 @@ TRACE_EVENT(ext3_drop_inode, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(drop, drop); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(drop, drop) > ), > > TP_printk("dev %d,%d ino %lu drop %d", > @@ -145,9 +145,9 @@ TRACE_EVENT(ext3_mark_inode_dirty, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(ip, IP); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(ip, IP) > ), > > TP_printk("dev %d,%d ino %lu caller %pF", > @@ -170,11 +170,11 @@ TRACE_EVENT(ext3_write_begin, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(pos, pos); > - tp_assign(len, len); > - tp_assign(flags, flags); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(pos, pos) > + tp_assign(len, len) > + tp_assign(flags, flags) > ), > > TP_printk("dev %d,%d ino %lu pos %llu len %u flags %u", > @@ -199,11 +199,11 @@ DECLARE_EVENT_CLASS(ext3__write_end, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(pos, pos); > - tp_assign(len, len); > - tp_assign(copied, copied); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(pos, pos) > + tp_assign(len, len) > + tp_assign(copied, copied) > ), > > TP_printk("dev %d,%d ino %lu pos %llu len %u copied %u", > @@ -250,9 +250,9 @@ DECLARE_EVENT_CLASS(ext3__page_op, > ), > > TP_fast_assign( > - tp_assign(index, page->index); > - tp_assign(ino, page->mapping->host->i_ino); > - tp_assign(dev, page->mapping->host->i_sb->s_dev); > + tp_assign(index, page->index) > + tp_assign(ino, page->mapping->host->i_ino) > + tp_assign(dev, page->mapping->host->i_sb->s_dev) > ), > > TP_printk("dev %d,%d ino %lu page_index %lu", > @@ -309,10 +309,10 @@ TRACE_EVENT(ext3_invalidatepage, > ), > > TP_fast_assign( > - tp_assign(index, page->index); > - tp_assign(offset, offset); > - tp_assign(ino, page->mapping->host->i_ino); > - tp_assign(dev, page->mapping->host->i_sb->s_dev); > + tp_assign(index, page->index) > + tp_assign(offset, offset) > + tp_assign(ino, page->mapping->host->i_ino) > + tp_assign(dev, page->mapping->host->i_sb->s_dev) > ), > > TP_printk("dev %d,%d ino %lu page_index %lu offset %lu", > @@ -335,9 +335,9 @@ TRACE_EVENT(ext3_discard_blocks, > ), > > TP_fast_assign( > - tp_assign(dev, sb->s_dev); > - tp_assign(blk, blk); > - tp_assign(count, count); > + tp_assign(dev, sb->s_dev) > + tp_assign(blk, blk) > + tp_assign(count, count) > ), > > TP_printk("dev %d,%d blk %lu count %lu", > @@ -359,10 +359,10 @@ TRACE_EVENT(ext3_request_blocks, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(count, count); > - tp_assign(goal, goal); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(count, count) > + tp_assign(goal, goal) > ), > > TP_printk("dev %d,%d ino %lu count %lu goal %lu ", > @@ -386,11 +386,11 @@ TRACE_EVENT(ext3_allocate_blocks, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(block, block); > - tp_assign(count, count); > - tp_assign(goal, goal); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(block, block) > + tp_assign(count, count) > + tp_assign(goal, goal) > ), > > TP_printk("dev %d,%d ino %lu count %lu block %lu goal %lu", > @@ -415,11 +415,11 @@ TRACE_EVENT(ext3_free_blocks, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(mode, inode->i_mode); > - tp_assign(block, block); > - tp_assign(count, count); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(mode, inode->i_mode) > + tp_assign(block, block) > + tp_assign(count, count) > ), > > TP_printk("dev %d,%d ino %lu mode 0%o block %lu count %lu", > @@ -443,10 +443,10 @@ TRACE_EVENT(ext3_sync_file_enter, > TP_fast_assign( > dentry = file->f_path.dentry; > > - tp_assign(dev, dentry->d_inode->i_sb->s_dev); > - tp_assign(ino, dentry->d_inode->i_ino); > - tp_assign(datasync, datasync); > - tp_assign(parent, dentry->d_parent->d_inode->i_ino); > + tp_assign(dev, dentry->d_inode->i_sb->s_dev) > + tp_assign(ino, dentry->d_inode->i_ino) > + tp_assign(datasync, datasync) > + tp_assign(parent, dentry->d_parent->d_inode->i_ino) > ), > > TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", > @@ -467,9 +467,9 @@ TRACE_EVENT(ext3_sync_file_exit, > ), > > TP_fast_assign( > - tp_assign(ret, ret); > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ret, ret) > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > ), > > TP_printk("dev %d,%d ino %lu ret %d", > @@ -490,8 +490,8 @@ TRACE_EVENT(ext3_sync_fs, > ), > > TP_fast_assign( > - tp_assign(dev, sb->s_dev); > - tp_assign(wait, wait); > + tp_assign(dev, sb->s_dev) > + tp_assign(wait, wait) > ), > > TP_printk("dev %d,%d wait %d", > @@ -512,9 +512,9 @@ TRACE_EVENT(ext3_rsv_window_add, > ), > > TP_fast_assign( > - tp_assign(dev, sb->s_dev); > - tp_assign(start, rsv_node->rsv_window._rsv_start); > - tp_assign(end, rsv_node->rsv_window._rsv_end); > + tp_assign(dev, sb->s_dev) > + tp_assign(start, rsv_node->rsv_window._rsv_start) > + tp_assign(end, rsv_node->rsv_window._rsv_end) > ), > > TP_printk("dev %d,%d start %lu end %lu", > @@ -536,10 +536,10 @@ TRACE_EVENT(ext3_discard_reservation, > ), > > TP_fast_assign( > - tp_assign(start, rsv_node->rsv_window._rsv_start); > - tp_assign(end, rsv_node->rsv_window._rsv_end); > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(start, rsv_node->rsv_window._rsv_start) > + tp_assign(end, rsv_node->rsv_window._rsv_end) > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > ), > > TP_printk("dev %d,%d ino %lu start %lu end %lu", > @@ -559,8 +559,8 @@ TRACE_EVENT(ext3_alloc_new_reservation, > ), > > TP_fast_assign( > - tp_assign(dev, sb->s_dev); > - tp_assign(goal, goal); > + tp_assign(dev, sb->s_dev) > + tp_assign(goal, goal) > ), > > TP_printk("dev %d,%d goal %lu", > @@ -582,10 +582,10 @@ TRACE_EVENT(ext3_reserved, > ), > > TP_fast_assign( > - tp_assign(block, block); > - tp_assign(start, rsv_node->rsv_window._rsv_start); > - tp_assign(end, rsv_node->rsv_window._rsv_end); > - tp_assign(dev, sb->s_dev); > + tp_assign(block, block) > + tp_assign(start, rsv_node->rsv_window._rsv_start) > + tp_assign(end, rsv_node->rsv_window._rsv_end) > + tp_assign(dev, sb->s_dev) > ), > > TP_printk("dev %d,%d block %lu, start %lu end %lu", > @@ -607,11 +607,11 @@ TRACE_EVENT(ext3_forget, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > - tp_assign(mode, inode->i_mode); > - tp_assign(is_metadata, is_metadata); > - tp_assign(block, block); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > + tp_assign(mode, inode->i_mode) > + tp_assign(is_metadata, is_metadata) > + tp_assign(block, block) > ), > > TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %lu", > @@ -632,8 +632,8 @@ TRACE_EVENT(ext3_read_block_bitmap, > ), > > TP_fast_assign( > - tp_assign(dev, sb->s_dev); > - tp_assign(group, group); > + tp_assign(dev, sb->s_dev) > + tp_assign(group, group) > ), > > TP_printk("dev %d,%d group %u", > @@ -655,11 +655,11 @@ TRACE_EVENT(ext3_direct_IO_enter, > ), > > TP_fast_assign( > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(pos, offset); > - tp_assign(len, len); > - tp_assign(rw, rw); > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(pos, offset) > + tp_assign(len, len) > + tp_assign(rw, rw) > ), > > TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d", > @@ -685,12 +685,12 @@ TRACE_EVENT(ext3_direct_IO_exit, > ), > > TP_fast_assign( > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(pos, offset); > - tp_assign(len, len); > - tp_assign(rw, rw); > - tp_assign(ret, ret); > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(pos, offset) > + tp_assign(len, len) > + tp_assign(rw, rw) > + tp_assign(ret, ret) > ), > > TP_printk("dev %d,%d ino %lu pos %llu len %lu rw %d ret %d", > @@ -713,10 +713,10 @@ TRACE_EVENT(ext3_unlink_enter, > ), > > TP_fast_assign( > - tp_assign(parent, parent->i_ino); > - tp_assign(ino, dentry->d_inode->i_ino); > - tp_assign(size, dentry->d_inode->i_size); > - tp_assign(dev, dentry->d_inode->i_sb->s_dev); > + tp_assign(parent, parent->i_ino) > + tp_assign(ino, dentry->d_inode->i_ino) > + tp_assign(size, dentry->d_inode->i_size) > + tp_assign(dev, dentry->d_inode->i_sb->s_dev) > ), > > TP_printk("dev %d,%d ino %lu size %lld parent %ld", > @@ -738,9 +738,9 @@ TRACE_EVENT(ext3_unlink_exit, > ), > > TP_fast_assign( > - tp_assign(ino, dentry->d_inode->i_ino); > - tp_assign(dev, dentry->d_inode->i_sb->s_dev); > - tp_assign(ret, ret); > + tp_assign(ino, dentry->d_inode->i_ino) > + tp_assign(dev, dentry->d_inode->i_sb->s_dev) > + tp_assign(ret, ret) > ), > > TP_printk("dev %d,%d ino %lu ret %d", > @@ -761,9 +761,9 @@ DECLARE_EVENT_CLASS(ext3__truncate, > ), > > TP_fast_assign( > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(blocks, inode->i_blocks); > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(blocks, inode->i_blocks) > ), > > TP_printk("dev %d,%d ino %lu blocks %lu", > @@ -800,11 +800,11 @@ TRACE_EVENT(ext3_get_blocks_enter, > ), > > TP_fast_assign( > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(lblk, lblk); > - tp_assign(len, len); > - tp_assign(create, create); > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(lblk, lblk) > + tp_assign(len, len) > + tp_assign(create, create) > ), > > TP_printk("dev %d,%d ino %lu lblk %lu len %lu create %u", > @@ -829,12 +829,12 @@ TRACE_EVENT(ext3_get_blocks_exit, > ), > > TP_fast_assign( > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(lblk, lblk); > - tp_assign(pblk, pblk); > - tp_assign(len, len); > - tp_assign(ret, ret); > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(lblk, lblk) > + tp_assign(pblk, pblk) > + tp_assign(len, len) > + tp_assign(ret, ret) > ), > > TP_printk("dev %d,%d ino %lu lblk %lu pblk %lu len %lu ret %d", > @@ -855,8 +855,8 @@ TRACE_EVENT(ext3_load_inode, > ), > > TP_fast_assign( > - tp_assign(ino, inode->i_ino); > - tp_assign(dev, inode->i_sb->s_dev); > + tp_assign(ino, inode->i_ino) > + tp_assign(dev, inode->i_sb->s_dev) > ), > > TP_printk("dev %d,%d ino %lu", > diff --git a/instrumentation/events/lttng-module/gpio.h b/instrumentation/events/lttng-module/gpio.h > index e6002c4..a0c5876 100644 > --- a/instrumentation/events/lttng-module/gpio.h > +++ b/instrumentation/events/lttng-module/gpio.h > @@ -19,9 +19,9 @@ TRACE_EVENT(gpio_direction, > ), > > TP_fast_assign( > - tp_assign(gpio, gpio); > - tp_assign(in, in); > - tp_assign(err, err); > + tp_assign(gpio, gpio) > + tp_assign(in, in) > + tp_assign(err, err) > ), > > TP_printk("%u %3s (%d)", __entry->gpio, > @@ -41,9 +41,9 @@ TRACE_EVENT(gpio_value, > ), > > TP_fast_assign( > - tp_assign(gpio, gpio); > - tp_assign(get, get); > - tp_assign(value, value); > + tp_assign(gpio, gpio) > + tp_assign(get, get) > + tp_assign(value, value) > ), > > TP_printk("%u %3s %d", __entry->gpio, > diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h > index 97ba1e5..b6bd64a 100644 > --- a/instrumentation/events/lttng-module/jbd.h > +++ b/instrumentation/events/lttng-module/jbd.h > @@ -19,8 +19,8 @@ TRACE_EVENT(jbd_checkpoint, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(result, result); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(result, result) > ), > > TP_printk("dev %d,%d result %d", > @@ -43,11 +43,11 @@ DECLARE_EVENT_CLASS(jbd_commit, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) > #endif > - tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(transaction, commit_transaction->t_tid) > ), > > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > @@ -104,11 +104,11 @@ TRACE_EVENT(jbd_drop_transaction, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) > #endif > - tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(transaction, commit_transaction->t_tid) > ), > > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > @@ -137,12 +137,12 @@ TRACE_EVENT(jbd_end_commit, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) > #endif > - tp_assign(transaction, commit_transaction->t_tid); > - tp_assign(head, journal->j_tail_sequence); > + tp_assign(transaction, commit_transaction->t_tid) > + tp_assign(head, journal->j_tail_sequence) > ), > > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > @@ -170,11 +170,11 @@ TRACE_EVENT(jbd_do_submit_data, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) > #endif > - tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(transaction, commit_transaction->t_tid) > ), > > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > @@ -204,11 +204,11 @@ TRACE_EVENT(jbd_cleanup_journal_tail, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(tail_sequence, journal->j_tail_sequence); > - tp_assign(first_tid, first_tid); > - tp_assign(block_nr, block_nr); > - tp_assign(freed, freed); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(tail_sequence, journal->j_tail_sequence) > + tp_assign(first_tid, first_tid) > + tp_assign(block_nr, block_nr) > + tp_assign(freed, freed) > ), > > TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > @@ -228,8 +228,8 @@ TRACE_EVENT(jbd_update_superblock_end, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(wait, wait); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(wait, wait) > ), > > TP_printk("dev %d,%d wait %d", > diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h > index 2e80832..91e2e6c 100644 > --- a/instrumentation/events/lttng-module/jbd2.h > +++ b/instrumentation/events/lttng-module/jbd2.h > @@ -148,16 +148,16 @@ TRACE_EVENT(jbd2_run_stats, > ), > > TP_fast_assign( > - tp_assign(dev, dev); > - tp_assign(tid, tid); > - tp_assign(wait, stats->rs_wait); > - tp_assign(running, stats->rs_running); > - tp_assign(locked, stats->rs_locked); > - tp_assign(flushing, stats->rs_flushing); > - tp_assign(logging, stats->rs_logging); > - tp_assign(handle_count, stats->rs_handle_count); > - tp_assign(blocks, stats->rs_blocks); > - tp_assign(blocks_logged, stats->rs_blocks_logged); > + tp_assign(dev, dev) > + tp_assign(tid, tid) > + tp_assign(wait, stats->rs_wait) > + tp_assign(running, stats->rs_running) > + tp_assign(locked, stats->rs_locked) > + tp_assign(flushing, stats->rs_flushing) > + tp_assign(logging, stats->rs_logging) > + tp_assign(handle_count, stats->rs_handle_count) > + tp_assign(blocks, stats->rs_blocks) > + tp_assign(blocks_logged, stats->rs_blocks_logged) > ), > > TP_printk("dev %d,%d tid %lu wait %u running %u locked %u flushing %u " > @@ -188,12 +188,12 @@ TRACE_EVENT(jbd2_checkpoint_stats, > ), > > TP_fast_assign( > - tp_assign(dev, dev); > - tp_assign(tid, tid); > - tp_assign(chp_time, stats->cs_chp_time); > - tp_assign(forced_to_close, stats->cs_forced_to_close); > - tp_assign(written, stats->cs_written); > - tp_assign(dropped, stats->cs_dropped); > + tp_assign(dev, dev) > + tp_assign(tid, tid) > + tp_assign(chp_time, stats->cs_chp_time) > + tp_assign(forced_to_close, stats->cs_forced_to_close) > + tp_assign(written, stats->cs_written) > + tp_assign(dropped, stats->cs_dropped) > ), > > TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u " > @@ -219,11 +219,11 @@ TRACE_EVENT(jbd2_cleanup_journal_tail, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(tail_sequence, journal->j_tail_sequence); > - tp_assign(first_tid, first_tid); > - tp_assign(block_nr, block_nr); > - tp_assign(freed, freed); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(tail_sequence, journal->j_tail_sequence) > + tp_assign(first_tid, first_tid) > + tp_assign(block_nr, block_nr) > + tp_assign(freed, freed) > ), > > TP_printk("dev %d,%d from %u to %u offset %lu freed %lu", > diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h > index 04f668b..dab8989 100644 > --- a/instrumentation/events/lttng-module/kmem.h > +++ b/instrumentation/events/lttng-module/kmem.h > @@ -23,11 +23,11 @@ DECLARE_EVENT_CLASS(kmem_alloc, > ), > > TP_fast_assign( > - tp_assign(call_site, call_site); > - tp_assign(ptr, ptr); > - tp_assign(bytes_req, bytes_req); > - tp_assign(bytes_alloc, bytes_alloc); > - tp_assign(gfp_flags, gfp_flags); > + tp_assign(call_site, call_site) > + tp_assign(ptr, ptr) > + tp_assign(bytes_req, bytes_req) > + tp_assign(bytes_alloc, bytes_alloc) > + tp_assign(gfp_flags, gfp_flags) > ), > > TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s", > @@ -75,12 +75,12 @@ DECLARE_EVENT_CLASS(kmem_alloc_node, > ), > > TP_fast_assign( > - tp_assign(call_site, call_site); > - tp_assign(ptr, ptr); > - tp_assign(bytes_req, bytes_req); > - tp_assign(bytes_alloc, bytes_alloc); > - tp_assign(gfp_flags, gfp_flags); > - tp_assign(node, node); > + tp_assign(call_site, call_site) > + tp_assign(ptr, ptr) > + tp_assign(bytes_req, bytes_req) > + tp_assign(bytes_alloc, bytes_alloc) > + tp_assign(gfp_flags, gfp_flags) > + tp_assign(node, node) > ), > > TP_printk("call_site=%lx ptr=%p bytes_req=%zu bytes_alloc=%zu gfp_flags=%s node=%d", > @@ -122,8 +122,8 @@ DECLARE_EVENT_CLASS(kmem_free, > ), > > TP_fast_assign( > - tp_assign(call_site, call_site); > - tp_assign(ptr, ptr); > + tp_assign(call_site, call_site) > + tp_assign(ptr, ptr) > ), > > TP_printk("call_site=%lx ptr=%p", __entry->call_site, __entry->ptr) > @@ -155,8 +155,8 @@ TRACE_EVENT(mm_page_free_direct, > ), > > TP_fast_assign( > - tp_assign(page, page); > - tp_assign(order, order); > + tp_assign(page, page) > + tp_assign(order, order) > ), > > TP_printk("page=%p pfn=%lu order=%d", > @@ -177,8 +177,8 @@ TRACE_EVENT(mm_pagevec_free, > ), > > TP_fast_assign( > - tp_assign(page, page); > - tp_assign(cold, cold); > + tp_assign(page, page) > + tp_assign(cold, cold) > ), > > TP_printk("page=%p pfn=%lu order=0 cold=%d", > @@ -202,10 +202,10 @@ TRACE_EVENT(mm_page_alloc, > ), > > TP_fast_assign( > - tp_assign(page, page); > - tp_assign(order, order); > - tp_assign(gfp_flags, gfp_flags); > - tp_assign(migratetype, migratetype); > + tp_assign(page, page) > + tp_assign(order, order) > + tp_assign(gfp_flags, gfp_flags) > + tp_assign(migratetype, migratetype) > ), > > TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > @@ -229,9 +229,9 @@ DECLARE_EVENT_CLASS(mm_page, > ), > > TP_fast_assign( > - tp_assign(page, page); > - tp_assign(order, order); > - tp_assign(migratetype, migratetype); > + tp_assign(page, page) > + tp_assign(order, order) > + tp_assign(migratetype, migratetype) > ), > > TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > @@ -279,11 +279,11 @@ TRACE_EVENT(mm_page_alloc_extfrag, > ), > > TP_fast_assign( > - tp_assign(page, page); > - tp_assign(alloc_order, alloc_order); > - tp_assign(fallback_order, fallback_order); > - tp_assign(alloc_migratetype, alloc_migratetype); > - tp_assign(fallback_migratetype, fallback_migratetype); > + tp_assign(page, page) > + tp_assign(alloc_order, alloc_order) > + tp_assign(fallback_order, fallback_order) > + tp_assign(alloc_migratetype, alloc_migratetype) > + tp_assign(fallback_migratetype, fallback_migratetype) > ), > > TP_printk("page=%p pfn=%lu alloc_order=%d fallback_order=%d pageblock_order=%d alloc_migratetype=%d fallback_migratetype=%d fragmenting=%d change_ownership=%d", > diff --git a/instrumentation/events/lttng-module/lock.h b/instrumentation/events/lttng-module/lock.h > index 75101f6..e2c1c7a 100644 > --- a/instrumentation/events/lttng-module/lock.h > +++ b/instrumentation/events/lttng-module/lock.h > @@ -24,9 +24,9 @@ TRACE_EVENT(lock_acquire, > ), > > TP_fast_assign( > - tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)); > - tp_strcpy(name, lock->name); > - tp_assign(lockdep_addr, lock); > + tp_assign(flags, (trylock ? 1 : 0) | (read ? 2 : 0)) > + tp_strcpy(name, lock->name) > + tp_assign(lockdep_addr, lock) > ), > > TP_printk("%p %s%s%s", __entry->lockdep_addr, > @@ -47,8 +47,8 @@ DECLARE_EVENT_CLASS(lock, > ), > > TP_fast_assign( > - tp_strcpy(name, lock->name); > - tp_assign(lockdep_addr, lock); > + tp_strcpy(name, lock->name) > + tp_assign(lockdep_addr, lock) > ), > > TP_printk("%p %s", __entry->lockdep_addr, __get_str(name)) > diff --git a/instrumentation/events/lttng-module/module.h b/instrumentation/events/lttng-module/module.h > index 2e83431..65a8135 100644 > --- a/instrumentation/events/lttng-module/module.h > +++ b/instrumentation/events/lttng-module/module.h > @@ -40,8 +40,8 @@ TRACE_EVENT(module_load, > ), > > TP_fast_assign( > - tp_assign(taints, mod->taints); > - tp_strcpy(name, mod->name); > + tp_assign(taints, mod->taints) > + tp_strcpy(name, mod->name) > ), > > TP_printk("%s %s", __get_str(name), show_module_flags(__entry->taints)) > @@ -58,7 +58,7 @@ TRACE_EVENT(module_free, > ), > > TP_fast_assign( > - tp_strcpy(name, mod->name); > + tp_strcpy(name, mod->name) > ), > > TP_printk("%s", __get_str(name)) > @@ -80,9 +80,9 @@ DECLARE_EVENT_CLASS(module_refcnt, > ), > > TP_fast_assign( > - tp_assign(ip, ip); > - tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)); > - tp_strcpy(name, mod->name); > + tp_assign(ip, ip) > + tp_assign(refcnt, __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs)) > + tp_strcpy(name, mod->name) > ), > > TP_printk("%s call_site=%pf refcnt=%d", > @@ -117,9 +117,9 @@ TRACE_EVENT(module_request, > ), > > TP_fast_assign( > - tp_assign(ip, ip); > - tp_assign(wait, wait); > - tp_strcpy(name, name); > + tp_assign(ip, ip) > + tp_assign(wait, wait) > + tp_strcpy(name, name) > ), > > TP_printk("%s wait=%d call_site=%pf", > diff --git a/instrumentation/events/lttng-module/napi.h b/instrumentation/events/lttng-module/napi.h > index 58b8336..26b10ba 100644 > --- a/instrumentation/events/lttng-module/napi.h > +++ b/instrumentation/events/lttng-module/napi.h > @@ -22,8 +22,8 @@ TRACE_EVENT(napi_poll, > ), > > TP_fast_assign( > - tp_assign(napi, napi); > - tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV); > + tp_assign(napi, napi) > + tp_strcpy(dev_name, napi->dev ? napi->dev->name : NO_DEV) > ), > > TP_printk("napi poll on napi struct %p for device %s", > diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h > index 589011c..a444b07 100644 > --- a/instrumentation/events/lttng-module/net.h > +++ b/instrumentation/events/lttng-module/net.h > @@ -39,17 +39,17 @@ TRACE_EVENT(net_dev_xmit, > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > TP_fast_assign( > - tp_assign(skbaddr, skb); > - tp_assign(len, skb_len); > - tp_assign(rc, rc); > - tp_strcpy(name, dev->name); > + tp_assign(skbaddr, skb) > + tp_assign(len, skb_len) > + tp_assign(rc, rc) > + tp_strcpy(name, dev->name) > ), > #else > TP_fast_assign( > - tp_assign(skbaddr, skb); > - tp_assign(len, skb->len); > - tp_assign(rc, rc); > - tp_strcpy(name, skb->dev->name); > + tp_assign(skbaddr, skb) > + tp_assign(len, skb->len) > + tp_assign(rc, rc) > + tp_strcpy(name, skb->dev->name) > ), > #endif > > @@ -70,9 +70,9 @@ DECLARE_EVENT_CLASS(net_dev_template, > ), > > TP_fast_assign( > - tp_assign(skbaddr, skb); > - tp_assign(len, skb->len); > - tp_strcpy(name, skb->dev->name); > + tp_assign(skbaddr, skb) > + tp_assign(len, skb->len) > + tp_strcpy(name, skb->dev->name) > ), > > TP_printk("dev=%s skbaddr=%p len=%u", > diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h > index 05aced7..f2e3f54 100644 > --- a/instrumentation/events/lttng-module/power.h > +++ b/instrumentation/events/lttng-module/power.h > @@ -19,8 +19,8 @@ DECLARE_EVENT_CLASS(cpu, > ), > > TP_fast_assign( > - tp_assign(state, state); > - tp_assign(cpu_id, cpu_id); > + tp_assign(state, state) > + tp_assign(cpu_id, cpu_id) > ), > > TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state, > @@ -59,7 +59,7 @@ TRACE_EVENT(machine_suspend, > ), > > TP_fast_assign( > - tp_assign(state, state); > + tp_assign(state, state) > ), > > TP_printk("state=%lu", (unsigned long)__entry->state) > @@ -85,9 +85,9 @@ DECLARE_EVENT_CLASS(power, > ), > > TP_fast_assign( > - tp_assign(type, type); > - tp_assign(state, state); > - tp_assign(cpu_id, cpu_id); > + tp_assign(type, type) > + tp_assign(state, state) > + tp_assign(cpu_id, cpu_id) > ), > > TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type, > @@ -119,7 +119,7 @@ TRACE_EVENT(power_end, > ), > > TP_fast_assign( > - tp_assign(cpu_id, cpu_id); > + tp_assign(cpu_id, cpu_id) > ), > > TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id) > @@ -173,9 +173,9 @@ DECLARE_EVENT_CLASS(clock, > ), > > TP_fast_assign( > - tp_strcpy(name, name); > - tp_assign(state, state); > - tp_assign(cpu_id, cpu_id); > + tp_strcpy(name, name) > + tp_assign(state, state) > + tp_assign(cpu_id, cpu_id) > ), > > TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > @@ -219,9 +219,9 @@ DECLARE_EVENT_CLASS(power_domain, > ), > > TP_fast_assign( > - tp_strcpy(name, name); > - tp_assign(state, state); > - tp_assign(cpu_id, cpu_id); > + tp_strcpy(name, name) > + tp_assign(state, state) > + tp_assign(cpu_id, cpu_id) > ), > > TP_printk("%s state=%lu cpu_id=%lu", __get_str(name), > diff --git a/instrumentation/events/lttng-module/regulator.h b/instrumentation/events/lttng-module/regulator.h > index e94da7c..bb84c47 100644 > --- a/instrumentation/events/lttng-module/regulator.h > +++ b/instrumentation/events/lttng-module/regulator.h > @@ -22,7 +22,7 @@ DECLARE_EVENT_CLASS(regulator_basic, > ), > > TP_fast_assign( > - tp_strcpy(name, name); > + tp_strcpy(name, name) > ), > > TP_printk("name=%s", __get_str(name)) > @@ -86,9 +86,9 @@ DECLARE_EVENT_CLASS(regulator_range, > ), > > TP_fast_assign( > - tp_strcpy(name, name); > - tp_assign(min, min); > - tp_assign(max, max); > + tp_strcpy(name, name) > + tp_assign(min, min) > + tp_assign(max, max) > ), > > TP_printk("name=%s (%d-%d)", __get_str(name), > @@ -119,8 +119,8 @@ DECLARE_EVENT_CLASS(regulator_value, > ), > > TP_fast_assign( > - tp_strcpy(name, name); > - tp_assign(val, val); > + tp_strcpy(name, name) > + tp_assign(val, val) > ), > > TP_printk("name=%s, val=%u", __get_str(name), > diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h > index 27362f8..18d2b02 100644 > --- a/instrumentation/events/lttng-module/scsi.h > +++ b/instrumentation/events/lttng-module/scsi.h > @@ -222,16 +222,16 @@ TRACE_EVENT(scsi_dispatch_cmd_start, > ), > > TP_fast_assign( > - tp_assign(host_no, cmd->device->host->host_no); > - tp_assign(channel, cmd->device->channel); > - tp_assign(id, cmd->device->id); > - tp_assign(lun, cmd->device->lun); > - tp_assign(opcode, cmd->cmnd[0]); > - tp_assign(cmd_len, cmd->cmd_len); > - tp_assign(data_sglen, scsi_sg_count(cmd)); > - tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > - tp_assign(prot_op, scsi_get_prot_op(cmd)); > - tp_memcpy_dyn(cmnd, cmd->cmnd); > + tp_assign(host_no, cmd->device->host->host_no) > + tp_assign(channel, cmd->device->channel) > + tp_assign(id, cmd->device->id) > + tp_assign(lun, cmd->device->lun) > + tp_assign(opcode, cmd->cmnd[0]) > + tp_assign(cmd_len, cmd->cmd_len) > + tp_assign(data_sglen, scsi_sg_count(cmd)) > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) > + tp_assign(prot_op, scsi_get_prot_op(cmd)) > + tp_memcpy_dyn(cmnd, cmd->cmnd) > ), > > TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > @@ -265,17 +265,17 @@ TRACE_EVENT(scsi_dispatch_cmd_error, > ), > > TP_fast_assign( > - tp_assign(host_no, cmd->device->host->host_no); > - tp_assign(channel, cmd->device->channel); > - tp_assign(id, cmd->device->id); > - tp_assign(lun, cmd->device->lun); > - tp_assign(rtn, rtn); > - tp_assign(opcode, cmd->cmnd[0]); > - tp_assign(cmd_len, cmd->cmd_len); > - tp_assign(data_sglen, scsi_sg_count(cmd)); > - tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > - tp_assign(prot_op, scsi_get_prot_op(cmd)); > - tp_memcpy_dyn(cmnd, cmd->cmnd); > + tp_assign(host_no, cmd->device->host->host_no) > + tp_assign(channel, cmd->device->channel) > + tp_assign(id, cmd->device->id) > + tp_assign(lun, cmd->device->lun) > + tp_assign(rtn, rtn) > + tp_assign(opcode, cmd->cmnd[0]) > + tp_assign(cmd_len, cmd->cmd_len) > + tp_assign(data_sglen, scsi_sg_count(cmd)) > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) > + tp_assign(prot_op, scsi_get_prot_op(cmd)) > + tp_memcpy_dyn(cmnd, cmd->cmnd) > ), > > TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > @@ -310,17 +310,17 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > ), > > TP_fast_assign( > - tp_assign(host_no, cmd->device->host->host_no); > - tp_assign(channel, cmd->device->channel); > - tp_assign(id, cmd->device->id); > - tp_assign(lun, cmd->device->lun); > - tp_assign(result, cmd->result); > - tp_assign(opcode, cmd->cmnd[0]); > - tp_assign(cmd_len, cmd->cmd_len); > - tp_assign(data_sglen, scsi_sg_count(cmd)); > - tp_assign(prot_sglen, scsi_prot_sg_count(cmd)); > - tp_assign(prot_op, scsi_get_prot_op(cmd)); > - tp_memcpy_dyn(cmnd, cmd->cmnd); > + tp_assign(host_no, cmd->device->host->host_no) > + tp_assign(channel, cmd->device->channel) > + tp_assign(id, cmd->device->id) > + tp_assign(lun, cmd->device->lun) > + tp_assign(result, cmd->result) > + tp_assign(opcode, cmd->cmnd[0]) > + tp_assign(cmd_len, cmd->cmd_len) > + tp_assign(data_sglen, scsi_sg_count(cmd)) > + tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) > + tp_assign(prot_op, scsi_get_prot_op(cmd)) > + tp_memcpy_dyn(cmnd, cmd->cmnd) > ), > > TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > @@ -357,7 +357,7 @@ TRACE_EVENT(scsi_eh_wakeup, > ), > > TP_fast_assign( > - tp_assign(host_no, shost->host_no); > + tp_assign(host_no, shost->host_no) > ), > > TP_printk("host_no=%u", __entry->host_no) > diff --git a/instrumentation/events/lttng-module/skb.h b/instrumentation/events/lttng-module/skb.h > index 9a79449..3163356 100644 > --- a/instrumentation/events/lttng-module/skb.h > +++ b/instrumentation/events/lttng-module/skb.h > @@ -24,9 +24,9 @@ TRACE_EVENT(kfree_skb, > ), > > TP_fast_assign( > - tp_assign(skbaddr, skb); > - tp_assign(location, location); > - tp_assign(protocol, ntohs(skb->protocol)); > + tp_assign(skbaddr, skb) > + tp_assign(location, location) > + tp_assign(protocol, ntohs(skb->protocol)) > ), > > TP_printk("skbaddr=%p protocol=%u location=%p", > @@ -44,7 +44,7 @@ TRACE_EVENT(consume_skb, > ), > > TP_fast_assign( > - tp_assign(skbaddr, skb); > + tp_assign(skbaddr, skb) > ), > > TP_printk("skbaddr=%p", __entry->skbaddr) > @@ -62,8 +62,8 @@ TRACE_EVENT(skb_copy_datagram_iovec, > ), > > TP_fast_assign( > - tp_assign(skbaddr, skb); > - tp_assign(len, len); > + tp_assign(skbaddr, skb) > + tp_assign(len, len) > ), > > TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len) > diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h > index 246ea58..c4e689a 100644 > --- a/instrumentation/events/lttng-module/sock.h > +++ b/instrumentation/events/lttng-module/sock.h > @@ -20,9 +20,9 @@ TRACE_EVENT(sock_rcvqueue_full, > ), > > TP_fast_assign( > - tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > - tp_assign(truesize, skb->truesize); > - tp_assign(sk_rcvbuf, sk->sk_rcvbuf); > + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)) > + tp_assign(truesize, skb->truesize) > + tp_assign(sk_rcvbuf, sk->sk_rcvbuf) > ), > > TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", > @@ -44,10 +44,10 @@ TRACE_EVENT(sock_exceed_buf_limit, > ), > > TP_fast_assign( > - tp_strcpy(name, prot->name); > - tp_assign(sysctl_mem, prot->sysctl_mem); > - tp_assign(allocated, allocated); > - tp_assign(sysctl_rmem, prot->sysctl_rmem[0]); > + tp_strcpy(name, prot->name) > + tp_assign(sysctl_mem, prot->sysctl_mem) > + tp_assign(allocated, allocated) > + tp_assign(sysctl_rmem, prot->sysctl_rmem[0]) > tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > ), > > diff --git a/instrumentation/events/lttng-module/udp.h b/instrumentation/events/lttng-module/udp.h > index 304ea95..a246e84 100644 > --- a/instrumentation/events/lttng-module/udp.h > +++ b/instrumentation/events/lttng-module/udp.h > @@ -19,8 +19,8 @@ TRACE_EVENT(udp_fail_queue_rcv_skb, > ), > > TP_fast_assign( > - tp_assign(rc, rc); > - tp_assign(lport, inet_sk(sk)->inet_num); > + tp_assign(rc, rc) > + tp_assign(lport, inet_sk(sk)->inet_num) > ), > > TP_printk("rc=%d port=%hu", __entry->rc, __entry->lport) > diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h > index aa022e2..d6ab952 100644 > --- a/instrumentation/events/lttng-module/vmscan.h > +++ b/instrumentation/events/lttng-module/vmscan.h > @@ -15,7 +15,7 @@ TRACE_EVENT(mm_vmscan_kswapd_sleep, > ), > > TP_fast_assign( > - tp_assign(nid, nid); > + tp_assign(nid, nid) > ), > > TP_printk("nid=%d", __entry->nid) > @@ -33,8 +33,8 @@ TRACE_EVENT(mm_vmscan_kswapd_wake, > ), > > TP_fast_assign( > - tp_assign(nid, nid); > - tp_assign(order, order); > + tp_assign(nid, nid) > + tp_assign(order, order) > ), > > TP_printk("nid=%d order=%d", __entry->nid, __entry->order) > @@ -53,9 +53,9 @@ TRACE_EVENT(mm_vmscan_wakeup_kswapd, > ), > > TP_fast_assign( > - tp_assign(nid, nid); > - tp_assign(zid, zid); > - tp_assign(order, order); > + tp_assign(nid, nid) > + tp_assign(zid, zid) > + tp_assign(order, order) > ), > > TP_printk("nid=%d zid=%d order=%d", > @@ -77,9 +77,9 @@ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template, > ), > > TP_fast_assign( > - tp_assign(order, order); > - tp_assign(may_writepage, may_writepage); > - tp_assign(gfp_flags, gfp_flags); > + tp_assign(order, order) > + tp_assign(may_writepage, may_writepage) > + tp_assign(gfp_flags, gfp_flags) > ), > > TP_printk("order=%d may_writepage=%d gfp_flags=%s", > @@ -120,7 +120,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, > ), > > TP_fast_assign( > - tp_assign(nr_reclaimed, nr_reclaimed); > + tp_assign(nr_reclaimed, nr_reclaimed) > ), > > TP_printk("nr_reclaimed=%lu", __entry->nr_reclaimed) > @@ -169,15 +169,15 @@ TRACE_EVENT(mm_shrink_slab_start, > ), > > TP_fast_assign( > - tp_assign(shr,shr); > - tp_assign(shrink, shr->shrink); > - tp_assign(nr_objects_to_shrink, nr_objects_to_shrink); > - tp_assign(gfp_flags, sc->gfp_mask); > - tp_assign(pgs_scanned, pgs_scanned); > - tp_assign(lru_pgs, lru_pgs); > - tp_assign(cache_items, cache_items); > - tp_assign(delta, delta); > - tp_assign(total_scan, total_scan); > + tp_assign(shr,shr) > + tp_assign(shrink, shr->shrink) > + tp_assign(nr_objects_to_shrink, nr_objects_to_shrink) > + tp_assign(gfp_flags, sc->gfp_mask) > + tp_assign(pgs_scanned, pgs_scanned) > + tp_assign(lru_pgs, lru_pgs) > + tp_assign(cache_items, cache_items) > + tp_assign(delta, delta) > + tp_assign(total_scan, total_scan) > ), > > TP_printk("%pF %p: objects to shrink %ld gfp_flags %s pgs_scanned %ld lru_pgs %ld cache items %ld delta %lld total_scan %ld", > @@ -208,12 +208,12 @@ TRACE_EVENT(mm_shrink_slab_end, > ), > > TP_fast_assign( > - tp_assign(shr, shr); > - tp_assign(shrink, shr->shrink); > - tp_assign(unused_scan, unused_scan_cnt); > - tp_assign(new_scan, new_scan_cnt); > - tp_assign(retval, shrinker_retval); > - tp_assign(total_scan, new_scan_cnt - unused_scan_cnt); > + tp_assign(shr, shr) > + tp_assign(shrink, shr->shrink) > + tp_assign(unused_scan, unused_scan_cnt) > + tp_assign(new_scan, new_scan_cnt) > + tp_assign(retval, shrinker_retval) > + tp_assign(total_scan, new_scan_cnt - unused_scan_cnt) > ), > > TP_printk("%pF %p: unused scan count %ld new scan count %ld total_scan %ld last shrinker return val %d", > @@ -262,16 +262,16 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > ), > > TP_fast_assign( > - tp_assign(order, order); > - tp_assign(nr_requested, nr_requested); > - tp_assign(nr_scanned, nr_scanned); > - tp_assign(nr_taken, nr_taken); > - tp_assign(nr_lumpy_taken, nr_lumpy_taken); > - tp_assign(nr_lumpy_dirty, nr_lumpy_dirty); > - tp_assign(nr_lumpy_failed, nr_lumpy_failed); > - tp_assign(isolate_mode, isolate_mode); > + tp_assign(order, order) > + tp_assign(nr_requested, nr_requested) > + tp_assign(nr_scanned, nr_scanned) > + tp_assign(nr_taken, nr_taken) > + tp_assign(nr_lumpy_taken, nr_lumpy_taken) > + tp_assign(nr_lumpy_dirty, nr_lumpy_dirty) > + tp_assign(nr_lumpy_failed, nr_lumpy_failed) > + tp_assign(isolate_mode, isolate_mode) > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > - tp_assign(file, file); > + tp_assign(file, file) > #endif > ), > > @@ -364,8 +364,8 @@ TRACE_EVENT(mm_vmscan_writepage, > ), > > TP_fast_assign( > - tp_assign(page, page); > - tp_assign(reclaim_flags, reclaim_flags); > + tp_assign(page, page) > + tp_assign(reclaim_flags, reclaim_flags) > ), > > TP_printk("page=%p pfn=%lu flags=%s", > @@ -392,12 +392,12 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > ), > > TP_fast_assign( > - tp_assign(nid, nid); > - tp_assign(zid, zid); > - tp_assign(nr_scanned, nr_scanned); > - tp_assign(nr_reclaimed, nr_reclaimed); > - tp_assign(priority, priority); > - tp_assign(reclaim_flags, reclaim_flags); > + tp_assign(nid, nid) > + tp_assign(zid, zid) > + tp_assign(nr_scanned, nr_scanned) > + tp_assign(nr_reclaimed, nr_reclaimed) > + tp_assign(priority, priority) > + tp_assign(reclaim_flags, reclaim_flags) > ), > > TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", > @@ -423,10 +423,10 @@ TRACE_EVENT(replace_swap_token, > ), > > TP_fast_assign( > - tp_assign(old_mm, old_mm); > - tp_assign(old_prio, old_mm ? old_mm->token_priority : 0); > - tp_assign(new_mm, new_mm); > - tp_assign(new_prio, new_mm->token_priority); > + tp_assign(old_mm, old_mm) > + tp_assign(old_prio, old_mm ? old_mm->token_priority : 0) > + tp_assign(new_mm, new_mm) > + tp_assign(new_prio, new_mm->token_priority) > ), > > TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", > @@ -444,7 +444,7 @@ DECLARE_EVENT_CLASS(put_swap_token_template, > ), > > TP_fast_assign( > - tp_assign(swap_token_mm, swap_token_mm); > + tp_assign(swap_token_mm, swap_token_mm) > ), > > TP_printk("token_mm=%p", __entry->swap_token_mm) > @@ -479,11 +479,11 @@ TRACE_EVENT_CONDITION(update_swap_token_priority, > ), > > TP_fast_assign( > - tp_assign(mm, mm); > - tp_assign(old_prio, old_prio); > - tp_assign(new_prio, mm->token_priority); > - tp_assign(swap_token_mm, swap_token_mm); > - tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0); > + tp_assign(mm, mm) > + tp_assign(old_prio, old_prio) > + tp_assign(new_prio, mm->token_priority) > + tp_assign(swap_token_mm, swap_token_mm) > + tp_assign(swap_token_prio, swap_token_mm ? swap_token_mm->token_priority : 0) > ), > > TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", > -- > 1.7.10.4 > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 14 11:07:58 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 14 Nov 2012 11:07:58 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Enable additional kernel probes In-Reply-To: <50A394DF.70607@mentor.com> References: <50A394DF.70607@mentor.com> Message-ID: <20121114160758.GB32677@Krystal> * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > To enable the extra kernel probes (see related thread: http://lists.lttng.org/pipermail/lttng-dev/2012-November/019046.html) the following patch is required for lttng-tools: > > From fbf7bdae4af6d082ce71bc0976628e5d24a515fc Mon Sep 17 00:00:00 2001 > From: Paul Woegerer > Date: Wed, 14 Nov 2012 13:49:45 +0100 > Subject: [PATCH] Add additional kernel probes to module list. Acked-by: Mathieu Desnoyers > > --- > src/bin/lttng-sessiond/modprobe.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c > index b3f2e57..f38d393 100644 > --- a/src/bin/lttng-sessiond/modprobe.c > +++ b/src/bin/lttng-sessiond/modprobe.c > @@ -44,13 +44,30 @@ const struct kern_modules_param kern_modules_list[] = { > { "lttng-ring-buffer-metadata-mmap-client", 1 }, > { "lttng-probe-lttng", 1 }, > { "lttng-types", 0 }, > + { "lttng-probe-asoc", 0 }, > { "lttng-probe-block", 0 }, > + { "lttng-probe-ext3", 0 }, > + { "lttng-probe-gpio", 0 }, > { "lttng-probe-irq", 0 }, > + { "lttng-probe-jbd", 0 }, > + { "lttng-probe-jbd2", 0 }, > + { "lttng-probe-kmem", 0 }, > { "lttng-probe-kvm", 0 }, > + { "lttng-probe-lock", 0 }, > + { "lttng-probe-modules", 0 }, > + { "lttng-probe-napi", 0 }, > + { "lttng-probe-net", 0 }, > + { "lttng-probe-power", 0 }, > + { "lttng-probe-regulator", 0 }, > { "lttng-probe-sched", 0 }, > + { "lttng-probe-scsi", 0 }, > { "lttng-probe-signal", 0 }, > + { "lttng-probe-skb", 0 }, > + { "lttng-probe-sock", 0 }, > { "lttng-probe-statedump", 0 }, > { "lttng-probe-timer", 0 }, > + { "lttng-probe-udp", 0 }, > + { "lttng-probe-vmscan", 0 }, > }; > > /* > -- > 1.7.10.4 > > > > -- > Paul Woegerer | SW Development Engineer > http://go.mentor.com/sourceryanalyzer > > Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria > Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS > > Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. > Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Wed Nov 14 11:18:57 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Wed, 14 Nov 2012 17:18:57 +0100 Subject: [lttng-dev] [PATCH lttng-modules] Additional kernel probes In-Reply-To: <20121114160737.GA32677@Krystal> References: <50A0FB68.5060100@mentor.com> <20121112142928.GB23655@Krystal> <50A36A7E.3000203@mentor.com> <20121114160737.GA32677@Krystal> Message-ID: <50A3C471.3020806@mentor.com> On 11/14/2012 05:07 PM, Mathieu Desnoyers wrote: > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: >> Fixed for all probes. >> See Subject: [PATCH 3/3] Remove semicolons in TP_fast_assign blocks. >> >> >> And now the updated patch series ... > > All merged. For next time, a few nits: please send each patch in a > separate email, and usually we don't put dots at the end of titles. > Also, if you can put your Signed-off-by at the end of the patch header, > it would follow our workflow entirely. I'll keep this workflow info in mind for coming patches. Thanks for merging, Paul -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From dgoulet at efficios.com Wed Nov 14 11:26:38 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 14 Nov 2012 11:26:38 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Enable additional kernel probes In-Reply-To: <50A394DF.70607@mentor.com> References: <50A394DF.70607@mentor.com> Message-ID: <50A3C63E.5020307@efficios.com> Merged! Thanks David Woegerer, Paul: > To enable the extra kernel probes (see related thread: http://lists.lttng.org/pipermail/lttng-dev/2012-November/019046.html) the following patch is required for lttng-tools: > > From fbf7bdae4af6d082ce71bc0976628e5d24a515fc Mon Sep 17 00:00:00 2001 > From: Paul Woegerer > Date: Wed, 14 Nov 2012 13:49:45 +0100 > Subject: [PATCH] Add additional kernel probes to module list. > > --- > src/bin/lttng-sessiond/modprobe.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c > index b3f2e57..f38d393 100644 > --- a/src/bin/lttng-sessiond/modprobe.c > +++ b/src/bin/lttng-sessiond/modprobe.c > @@ -44,13 +44,30 @@ const struct kern_modules_param kern_modules_list[] = { > { "lttng-ring-buffer-metadata-mmap-client", 1 }, > { "lttng-probe-lttng", 1 }, > { "lttng-types", 0 }, > + { "lttng-probe-asoc", 0 }, > { "lttng-probe-block", 0 }, > + { "lttng-probe-ext3", 0 }, > + { "lttng-probe-gpio", 0 }, > { "lttng-probe-irq", 0 }, > + { "lttng-probe-jbd", 0 }, > + { "lttng-probe-jbd2", 0 }, > + { "lttng-probe-kmem", 0 }, > { "lttng-probe-kvm", 0 }, > + { "lttng-probe-lock", 0 }, > + { "lttng-probe-modules", 0 }, > + { "lttng-probe-napi", 0 }, > + { "lttng-probe-net", 0 }, > + { "lttng-probe-power", 0 }, > + { "lttng-probe-regulator", 0 }, > { "lttng-probe-sched", 0 }, > + { "lttng-probe-scsi", 0 }, > { "lttng-probe-signal", 0 }, > + { "lttng-probe-skb", 0 }, > + { "lttng-probe-sock", 0 }, > { "lttng-probe-statedump", 0 }, > { "lttng-probe-timer", 0 }, > + { "lttng-probe-udp", 0 }, > + { "lttng-probe-vmscan", 0 }, > }; > > /* From yannick.brosseau at gmail.com Wed Nov 14 11:33:04 2012 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Wed, 14 Nov 2012 11:33:04 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Enable additional kernel probes In-Reply-To: <50A3C63E.5020307@efficios.com> References: <50A394DF.70607@mentor.com> <50A3C63E.5020307@efficios.com> Message-ID: <50A3C7C0.4020107@gmail.com> Just wondering, would it be possible to have an autodetection mechanism to load all available probe module? (or having a configuration file for this list?) I'm thinking of the use case of people who would not want to load all modules or provide a custom probe module. On 2012-11-14 11:26, David Goulet wrote: > Merged! > > Thanks > David > > Woegerer, Paul: >> To enable the extra kernel probes (see related thread: http://lists.lttng.org/pipermail/lttng-dev/2012-November/019046.html) the following patch is required for lttng-tools: >> >> From fbf7bdae4af6d082ce71bc0976628e5d24a515fc Mon Sep 17 00:00:00 2001 >> From: Paul Woegerer >> Date: Wed, 14 Nov 2012 13:49:45 +0100 >> Subject: [PATCH] Add additional kernel probes to module list. >> >> --- >> src/bin/lttng-sessiond/modprobe.c | 17 +++++++++++++++++ >> 1 file changed, 17 insertions(+) >> >> diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c >> index b3f2e57..f38d393 100644 >> --- a/src/bin/lttng-sessiond/modprobe.c >> +++ b/src/bin/lttng-sessiond/modprobe.c >> @@ -44,13 +44,30 @@ const struct kern_modules_param kern_modules_list[] = { >> { "lttng-ring-buffer-metadata-mmap-client", 1 }, >> { "lttng-probe-lttng", 1 }, >> { "lttng-types", 0 }, >> + { "lttng-probe-asoc", 0 }, >> { "lttng-probe-block", 0 }, >> + { "lttng-probe-ext3", 0 }, >> + { "lttng-probe-gpio", 0 }, >> { "lttng-probe-irq", 0 }, >> + { "lttng-probe-jbd", 0 }, >> + { "lttng-probe-jbd2", 0 }, >> + { "lttng-probe-kmem", 0 }, >> { "lttng-probe-kvm", 0 }, >> + { "lttng-probe-lock", 0 }, >> + { "lttng-probe-modules", 0 }, >> + { "lttng-probe-napi", 0 }, >> + { "lttng-probe-net", 0 }, >> + { "lttng-probe-power", 0 }, >> + { "lttng-probe-regulator", 0 }, >> { "lttng-probe-sched", 0 }, >> + { "lttng-probe-scsi", 0 }, >> { "lttng-probe-signal", 0 }, >> + { "lttng-probe-skb", 0 }, >> + { "lttng-probe-sock", 0 }, >> { "lttng-probe-statedump", 0 }, >> { "lttng-probe-timer", 0 }, >> + { "lttng-probe-udp", 0 }, >> + { "lttng-probe-vmscan", 0 }, >> }; >> >> /* > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From dgoulet at efficios.com Wed Nov 14 11:35:26 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 14 Nov 2012 11:35:26 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Enable additional kernel probes In-Reply-To: <50A3C7C0.4020107@gmail.com> References: <50A394DF.70607@mentor.com> <50A3C63E.5020307@efficios.com> <50A3C7C0.4020107@gmail.com> Message-ID: <50A3C84E.60703@efficios.com> Ideally, a configuration file would be the way to go but we don't have one yet for the session daemon. I can't say when it will be available... Cheers! David Yannick Brosseau: > Just wondering, would it be possible to have an autodetection mechanism > to load all available probe module? > > (or having a configuration file for this list?) > > I'm thinking of the use case of people who would not want to load all > modules or provide a custom probe module. > > On 2012-11-14 11:26, David Goulet wrote: >> Merged! >> >> Thanks >> David >> >> Woegerer, Paul: >>> To enable the extra kernel probes (see related thread: http://lists.lttng.org/pipermail/lttng-dev/2012-November/019046.html) the following patch is required for lttng-tools: >>> >>> From fbf7bdae4af6d082ce71bc0976628e5d24a515fc Mon Sep 17 00:00:00 2001 >>> From: Paul Woegerer >>> Date: Wed, 14 Nov 2012 13:49:45 +0100 >>> Subject: [PATCH] Add additional kernel probes to module list. >>> >>> --- >>> src/bin/lttng-sessiond/modprobe.c | 17 +++++++++++++++++ >>> 1 file changed, 17 insertions(+) >>> >>> diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c >>> index b3f2e57..f38d393 100644 >>> --- a/src/bin/lttng-sessiond/modprobe.c >>> +++ b/src/bin/lttng-sessiond/modprobe.c >>> @@ -44,13 +44,30 @@ const struct kern_modules_param kern_modules_list[] = { >>> { "lttng-ring-buffer-metadata-mmap-client", 1 }, >>> { "lttng-probe-lttng", 1 }, >>> { "lttng-types", 0 }, >>> + { "lttng-probe-asoc", 0 }, >>> { "lttng-probe-block", 0 }, >>> + { "lttng-probe-ext3", 0 }, >>> + { "lttng-probe-gpio", 0 }, >>> { "lttng-probe-irq", 0 }, >>> + { "lttng-probe-jbd", 0 }, >>> + { "lttng-probe-jbd2", 0 }, >>> + { "lttng-probe-kmem", 0 }, >>> { "lttng-probe-kvm", 0 }, >>> + { "lttng-probe-lock", 0 }, >>> + { "lttng-probe-modules", 0 }, >>> + { "lttng-probe-napi", 0 }, >>> + { "lttng-probe-net", 0 }, >>> + { "lttng-probe-power", 0 }, >>> + { "lttng-probe-regulator", 0 }, >>> { "lttng-probe-sched", 0 }, >>> + { "lttng-probe-scsi", 0 }, >>> { "lttng-probe-signal", 0 }, >>> + { "lttng-probe-skb", 0 }, >>> + { "lttng-probe-sock", 0 }, >>> { "lttng-probe-statedump", 0 }, >>> { "lttng-probe-timer", 0 }, >>> + { "lttng-probe-udp", 0 }, >>> + { "lttng-probe-vmscan", 0 }, >>> }; >>> >>> /* >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From simon.marchi at polymtl.ca Wed Nov 14 16:50:53 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Wed, 14 Nov 2012 16:50:53 -0500 Subject: [lttng-dev] [PATCH urcu] runtests: check for existence of /usr/bin/time Message-ID: <1352929853-13417-1-git-send-email-simon.marchi@polymtl.ca> Otherwise, if /usr/bin/time does not exist, the tests won't run at all. Signed-off-by: Simon Marchi --- tests/runtests-batch.sh | 8 +++++++- tests/runtests.sh | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh index 6c2340d..d11609e 100755 --- a/tests/runtests-batch.sh +++ b/tests/runtests-batch.sh @@ -1,8 +1,14 @@ #!/bin/sh +if [ -x /usr/bin/time ]; then + TIME_COMMAND="/usr/bin/time -a -o runnall.detail.log" +else + TIME_COMMAND="" +fi + #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do for a in test_urcu_gc; do echo "./${a} $*" | tee -a runall.detail.log - /usr/bin/time -a -o runall.detail.log ./${a} $* + $TIME_COMMAND ./${a} $* done diff --git a/tests/runtests.sh b/tests/runtests.sh index 79e54df..563ebd3 100755 --- a/tests/runtests.sh +++ b/tests/runtests.sh @@ -1,10 +1,16 @@ #!/bin/sh +if [ -x /usr/bin/time ]; then + TIME_COMMAND="/usr/bin/time -a -o runnall.detail.log" +else + TIME_COMMAND="" +fi + for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ test_rwlock test_perthreadlock test_mutex; do echo "./${a} $*" | tee -a runall.detail.log - /usr/bin/time -a -o runall.detail.log ./${a} $* + $TIME_COMMAND ./${a} $* done -- 1.7.1 From mathieu.desnoyers at efficios.com Wed Nov 14 17:00:00 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 14 Nov 2012 17:00:00 -0500 Subject: [lttng-dev] [PATCH urcu] runtests: check for existence of /usr/bin/time In-Reply-To: <1352929853-13417-1-git-send-email-simon.marchi@polymtl.ca> References: <1352929853-13417-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121114220000.GA7992@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Otherwise, if /usr/bin/time does not exist, the tests won't run at all. Hrm, wouldn't it be better if configure.ac checks that time is there ? Thanks, Mathieu > > Signed-off-by: Simon Marchi > --- > tests/runtests-batch.sh | 8 +++++++- > tests/runtests.sh | 8 +++++++- > 2 files changed, 14 insertions(+), 2 deletions(-) > > diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh > index 6c2340d..d11609e 100755 > --- a/tests/runtests-batch.sh > +++ b/tests/runtests-batch.sh > @@ -1,8 +1,14 @@ > #!/bin/sh > > +if [ -x /usr/bin/time ]; then > + TIME_COMMAND="/usr/bin/time -a -o runnall.detail.log" > +else > + TIME_COMMAND="" > +fi > + > #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do > for a in test_urcu_gc; do > echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + $TIME_COMMAND ./${a} $* > done > > diff --git a/tests/runtests.sh b/tests/runtests.sh > index 79e54df..563ebd3 100755 > --- a/tests/runtests.sh > +++ b/tests/runtests.sh > @@ -1,10 +1,16 @@ > #!/bin/sh > > +if [ -x /usr/bin/time ]; then > + TIME_COMMAND="/usr/bin/time -a -o runnall.detail.log" > +else > + TIME_COMMAND="" > +fi > + > for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ > test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ > test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ > test_rwlock test_perthreadlock test_mutex; do > echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + $TIME_COMMAND ./${a} $* > done > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Wed Nov 14 23:24:45 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Wed, 14 Nov 2012 23:24:45 -0500 Subject: [lttng-dev] [PATCH] runtests: Make path of time binary configurable Message-ID: <1352953485-29736-1-git-send-email-simon.marchi@polymtl.ca> I work on a platform that does not come with a time program. This patch makes it possible to specify the path of the time binary or not use it if none is available. If the URCU_TEST_TIME_BIN environment variable exists and is executable, it is used. Otherwise it tries with /usr/bin/time, the most common location. If it is not there, the tests are ran without timing info. Signed-off-by: Simon Marchi --- tests/common.sh | 13 +++++++++++++ tests/runtests-batch.sh | 15 +++++++++++++-- tests/runtests.sh | 15 +++++++++++++-- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100755 tests/common.sh diff --git a/tests/common.sh b/tests/common.sh new file mode 100755 index 0000000..a321bf2 --- /dev/null +++ b/tests/common.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# +# This file is meant to be sourced from other tests scripts. +# + +if [ -x "$URCU_TEST_TIME_BIN" ]; then + test_time_bin="$URCU_TEST_TIME_BIN" +elif [ -x "/usr/bin/time" ]; then + test_time_bin="/usr/bin/time" +else + test_time_bin="" +fi + diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh index 6c2340d..222069c 100755 --- a/tests/runtests-batch.sh +++ b/tests/runtests-batch.sh @@ -1,8 +1,19 @@ #!/bin/sh +source "./common.sh" + +log_file="runall.detail.log" + +# Check if time bin is defined +if [ -n "$test_time_bin" ]; then + time_command="$test_time_bin -a -o $log_file" +else + time_command="" +fi + #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do for a in test_urcu_gc; do - echo "./${a} $*" | tee -a runall.detail.log - /usr/bin/time -a -o runall.detail.log ./${a} $* + echo "./${a} $*" | tee -a "$log_file" + $time_command ./${a} $* done diff --git a/tests/runtests.sh b/tests/runtests.sh index 79e54df..b3d3dc2 100755 --- a/tests/runtests.sh +++ b/tests/runtests.sh @@ -1,10 +1,21 @@ #!/bin/sh +source "./common.sh" + +log_file="runall.detail.log" + +# Check if time bin is defined +if [ -n "$test_time_bin" ]; then + time_command="$test_time_bin -a -o $log_file" +else + time_command="" +fi + for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ test_rwlock test_perthreadlock test_mutex; do - echo "./${a} $*" | tee -a runall.detail.log - /usr/bin/time -a -o runall.detail.log ./${a} $* + echo "./${a} $*" | tee -a "$log_file" + $time_command ./${a} $* done -- 1.7.1 From mathieu.desnoyers at efficios.com Thu Nov 15 00:00:17 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 15 Nov 2012 00:00:17 -0500 Subject: [lttng-dev] [PATCH] runtests: Make path of time binary configurable In-Reply-To: <1352953485-29736-1-git-send-email-simon.marchi@polymtl.ca> References: <1352953485-29736-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121115050017.GA19512@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > I work on a platform that does not come with a time program. This patch > makes it possible to specify the path of the time binary or not use it > if none is available. > > If the URCU_TEST_TIME_BIN environment variable exists and is executable, > it is used. Otherwise it tries with /usr/bin/time, the most common > location. If it is not there, the tests are ran without timing info. > > Signed-off-by: Simon Marchi > --- > tests/common.sh | 13 +++++++++++++ > tests/runtests-batch.sh | 15 +++++++++++++-- > tests/runtests.sh | 15 +++++++++++++-- > 3 files changed, 39 insertions(+), 4 deletions(-) > create mode 100755 tests/common.sh > > diff --git a/tests/common.sh b/tests/common.sh > new file mode 100755 > index 0000000..a321bf2 > --- /dev/null > +++ b/tests/common.sh > @@ -0,0 +1,13 @@ > +#!/bin/sh If it is meant to be sourced from other files, then the #!/bin/sh header is useless. Mainly because common.sh is useless when not sourced from other scripts (useless indivitually). > +# > +# This file is meant to be sourced from other tests scripts. > +# > + > +if [ -x "$URCU_TEST_TIME_BIN" ]; then > + test_time_bin="$URCU_TEST_TIME_BIN" We use capital letters to represent "variables" (which are really environment variables) in bash. e.g.: test_time_bin -> TEST_TIME_BIN Same for log_file and time_command. Thanks, Mathieu > +elif [ -x "/usr/bin/time" ]; then > + test_time_bin="/usr/bin/time" > +else > + test_time_bin="" > +fi > + > diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh > index 6c2340d..222069c 100755 > --- a/tests/runtests-batch.sh > +++ b/tests/runtests-batch.sh > @@ -1,8 +1,19 @@ > #!/bin/sh > > +source "./common.sh" > + > +log_file="runall.detail.log" > + > +# Check if time bin is defined > +if [ -n "$test_time_bin" ]; then > + time_command="$test_time_bin -a -o $log_file" > +else > + time_command="" > +fi > + > #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do > for a in test_urcu_gc; do > - echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + echo "./${a} $*" | tee -a "$log_file" > + $time_command ./${a} $* > done > > diff --git a/tests/runtests.sh b/tests/runtests.sh > index 79e54df..b3d3dc2 100755 > --- a/tests/runtests.sh > +++ b/tests/runtests.sh > @@ -1,10 +1,21 @@ > #!/bin/sh > > +source "./common.sh" > + > +log_file="runall.detail.log" > + > +# Check if time bin is defined > +if [ -n "$test_time_bin" ]; then > + time_command="$test_time_bin -a -o $log_file" > +else > + time_command="" > +fi > + > for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ > test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ > test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ > test_rwlock test_perthreadlock test_mutex; do > - echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + echo "./${a} $*" | tee -a "$log_file" > + $time_command ./${a} $* > done > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Thu Nov 15 00:25:09 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Thu, 15 Nov 2012 00:25:09 -0500 Subject: [lttng-dev] [PATCH] runtests: Make path of time binary configurable In-Reply-To: <20121115050017.GA19512@Krystal> References: <1352953485-29736-1-git-send-email-simon.marchi@polymtl.ca> <20121115050017.GA19512@Krystal> Message-ID: On Thu, Nov 15, 2012 at 12:00 AM, Mathieu Desnoyers wrote: > * Simon Marchi (simon.marchi at polymtl.ca) wrote: >> I work on a platform that does not come with a time program. This patch >> makes it possible to specify the path of the time binary or not use it >> if none is available. >> >> If the URCU_TEST_TIME_BIN environment variable exists and is executable, >> it is used. Otherwise it tries with /usr/bin/time, the most common >> location. If it is not there, the tests are ran without timing info. >> >> Signed-off-by: Simon Marchi >> --- >> tests/common.sh | 13 +++++++++++++ >> tests/runtests-batch.sh | 15 +++++++++++++-- >> tests/runtests.sh | 15 +++++++++++++-- >> 3 files changed, 39 insertions(+), 4 deletions(-) >> create mode 100755 tests/common.sh >> >> diff --git a/tests/common.sh b/tests/common.sh >> new file mode 100755 >> index 0000000..a321bf2 >> --- /dev/null >> +++ b/tests/common.sh >> @@ -0,0 +1,13 @@ >> +#!/bin/sh > > If it is meant to be sourced from other files, then the #!/bin/sh header > is useless. Mainly because common.sh is useless when not sourced from > other scripts (useless indivitually). Right. >> +# >> +# This file is meant to be sourced from other tests scripts. >> +# >> + >> +if [ -x "$URCU_TEST_TIME_BIN" ]; then >> + test_time_bin="$URCU_TEST_TIME_BIN" > > We use capital letters to represent "variables" (which are really > environment variables) in bash. > > e.g.: test_time_bin -> TEST_TIME_BIN > > Same for log_file and time_command. If I understand correctly, it is not an environment variable until you export it (thus make it available to child processes). There is such a thing plain variable, there is just one big scope. I think there is not a single right way to do this, but I tend to agree with the SO answer below. By using capitalized names, you risk interfering with important environment variables. It would be a shame to do PATH="/tmp/something" by accident. The answer I am referring to: http://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization. > Thanks, > > Mathieu > >> +elif [ -x "/usr/bin/time" ]; then >> + test_time_bin="/usr/bin/time" >> +else >> + test_time_bin="" >> +fi >> + >> diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh >> index 6c2340d..222069c 100755 >> --- a/tests/runtests-batch.sh >> +++ b/tests/runtests-batch.sh >> @@ -1,8 +1,19 @@ >> #!/bin/sh >> >> +source "./common.sh" >> + >> +log_file="runall.detail.log" >> + >> +# Check if time bin is defined >> +if [ -n "$test_time_bin" ]; then >> + time_command="$test_time_bin -a -o $log_file" >> +else >> + time_command="" >> +fi >> + >> #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do >> for a in test_urcu_gc; do >> - echo "./${a} $*" | tee -a runall.detail.log >> - /usr/bin/time -a -o runall.detail.log ./${a} $* >> + echo "./${a} $*" | tee -a "$log_file" >> + $time_command ./${a} $* >> done >> >> diff --git a/tests/runtests.sh b/tests/runtests.sh >> index 79e54df..b3d3dc2 100755 >> --- a/tests/runtests.sh >> +++ b/tests/runtests.sh >> @@ -1,10 +1,21 @@ >> #!/bin/sh >> >> +source "./common.sh" >> + >> +log_file="runall.detail.log" >> + >> +# Check if time bin is defined >> +if [ -n "$test_time_bin" ]; then >> + time_command="$test_time_bin -a -o $log_file" >> +else >> + time_command="" >> +fi >> + >> for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ >> test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ >> test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ >> test_rwlock test_perthreadlock test_mutex; do >> - echo "./${a} $*" | tee -a runall.detail.log >> - /usr/bin/time -a -o runall.detail.log ./${a} $* >> + echo "./${a} $*" | tee -a "$log_file" >> + $time_command ./${a} $* >> done >> >> -- >> 1.7.1 >> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com From raphael.beamonte at polymtl.ca Thu Nov 15 00:59:48 2012 From: raphael.beamonte at polymtl.ca (=?ISO-8859-1?Q?Rapha=EBl_Beamonte?=) Date: Thu, 15 Nov 2012 00:59:48 -0500 Subject: [lttng-dev] [PATCH] runtests: Make path of time binary configurable In-Reply-To: References: <1352953485-29736-1-git-send-email-simon.marchi@polymtl.ca> <20121115050017.GA19512@Krystal> Message-ID: > > If I understand correctly, it is not an environment variable until you > export it (thus make it available to child processes). There is such a > thing plain variable, there is just one big scope. I think there is > not a single right way to do this, but I tend to agree with the SO > answer below. By using capitalized names, you risk interfering with > important environment variables. It would be a shame to do > PATH="/tmp/something" by accident. > > The answer I am referring to: > > http://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization > . > I approve what Simon says. There is no real convention, and it is common to use "_"-separated variables names for non-exported ones, to be able to distinguish which one was/will be exported. In fact, it is also "promoted" by this book : http://goo.gl/IBFza (read full paragraph, there is a part on the next page) On the other hand, it is commonly said that if you work on a bash script that already has a convention, you have to be consistent to it. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mathieu.desnoyers at efficios.com Thu Nov 15 08:42:51 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 15 Nov 2012 08:42:51 -0500 Subject: [lttng-dev] [PATCH] runtests: Make path of time binary configurable In-Reply-To: References: <1352953485-29736-1-git-send-email-simon.marchi@polymtl.ca> <20121115050017.GA19512@Krystal> Message-ID: <20121115134251.GA25268@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > On Thu, Nov 15, 2012 at 12:00 AM, Mathieu Desnoyers > wrote: > > * Simon Marchi (simon.marchi at polymtl.ca) wrote: > >> I work on a platform that does not come with a time program. This patch > >> makes it possible to specify the path of the time binary or not use it > >> if none is available. > >> > >> If the URCU_TEST_TIME_BIN environment variable exists and is executable, > >> it is used. Otherwise it tries with /usr/bin/time, the most common > >> location. If it is not there, the tests are ran without timing info. > >> > >> Signed-off-by: Simon Marchi > >> --- > >> tests/common.sh | 13 +++++++++++++ > >> tests/runtests-batch.sh | 15 +++++++++++++-- > >> tests/runtests.sh | 15 +++++++++++++-- > >> 3 files changed, 39 insertions(+), 4 deletions(-) > >> create mode 100755 tests/common.sh > >> > >> diff --git a/tests/common.sh b/tests/common.sh > >> new file mode 100755 > >> index 0000000..a321bf2 > >> --- /dev/null > >> +++ b/tests/common.sh > >> @@ -0,0 +1,13 @@ > >> +#!/bin/sh > > > > If it is meant to be sourced from other files, then the #!/bin/sh header > > is useless. Mainly because common.sh is useless when not sourced from > > other scripts (useless indivitually). > > Right. > > >> +# > >> +# This file is meant to be sourced from other tests scripts. > >> +# > >> + > >> +if [ -x "$URCU_TEST_TIME_BIN" ]; then > >> + test_time_bin="$URCU_TEST_TIME_BIN" > > > > We use capital letters to represent "variables" (which are really > > environment variables) in bash. > > > > e.g.: test_time_bin -> TEST_TIME_BIN > > > > Same for log_file and time_command. > > If I understand correctly, it is not an environment variable until you > export it (thus make it available to child processes). There is such a > thing plain variable, there is just one big scope. I think there is > not a single right way to do this, but I tend to agree with the SO > answer below. By using capitalized names, you risk interfering with > important environment variables. It would be a shame to do > PATH="/tmp/something" by accident. > > The answer I am referring to: > http://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization. That's a compelling argument, I'll gradually adapt my bash coding style then, Thanks, Mathieu > > > Thanks, > > > > Mathieu > > > >> +elif [ -x "/usr/bin/time" ]; then > >> + test_time_bin="/usr/bin/time" > >> +else > >> + test_time_bin="" > >> +fi > >> + > >> diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh > >> index 6c2340d..222069c 100755 > >> --- a/tests/runtests-batch.sh > >> +++ b/tests/runtests-batch.sh > >> @@ -1,8 +1,19 @@ > >> #!/bin/sh > >> > >> +source "./common.sh" > >> + > >> +log_file="runall.detail.log" > >> + > >> +# Check if time bin is defined > >> +if [ -n "$test_time_bin" ]; then > >> + time_command="$test_time_bin -a -o $log_file" > >> +else > >> + time_command="" > >> +fi > >> + > >> #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do > >> for a in test_urcu_gc; do > >> - echo "./${a} $*" | tee -a runall.detail.log > >> - /usr/bin/time -a -o runall.detail.log ./${a} $* > >> + echo "./${a} $*" | tee -a "$log_file" > >> + $time_command ./${a} $* > >> done > >> > >> diff --git a/tests/runtests.sh b/tests/runtests.sh > >> index 79e54df..b3d3dc2 100755 > >> --- a/tests/runtests.sh > >> +++ b/tests/runtests.sh > >> @@ -1,10 +1,21 @@ > >> #!/bin/sh > >> > >> +source "./common.sh" > >> + > >> +log_file="runall.detail.log" > >> + > >> +# Check if time bin is defined > >> +if [ -n "$test_time_bin" ]; then > >> + time_command="$test_time_bin -a -o $log_file" > >> +else > >> + time_command="" > >> +fi > >> + > >> for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ > >> test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ > >> test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ > >> test_rwlock test_perthreadlock test_mutex; do > >> - echo "./${a} $*" | tee -a runall.detail.log > >> - /usr/bin/time -a -o runall.detail.log ./${a} $* > >> + echo "./${a} $*" | tee -a "$log_file" > >> + $time_command ./${a} $* > >> done > >> > >> -- > >> 1.7.1 > >> > >> > >> _______________________________________________ > >> lttng-dev mailing list > >> lttng-dev at lists.lttng.org > >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Thu Nov 15 09:01:59 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Thu, 15 Nov 2012 09:01:59 -0500 Subject: [lttng-dev] [PATCH urcu v2] runtests: Make path of time binary configurable Message-ID: <1352988119-2312-1-git-send-email-simon.marchi@polymtl.ca> I work on a platform that does not come with a time program. This patch makes it possible to specify the path of the time binary or not use it if none is available. If the URCU_TEST_TIME_BIN environment variable exists and is executable, it is used. Otherwise it tries with /usr/bin/time, the most common location. If it is not there, the tests are ran without timing info. Signed-off-by: Simon Marchi --- New in v2: removed #!/bin/sh at top of common.sh. tests/common.sh | 12 ++++++++++++ tests/runtests-batch.sh | 15 +++++++++++++-- tests/runtests.sh | 15 +++++++++++++-- 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100755 tests/common.sh diff --git a/tests/common.sh b/tests/common.sh new file mode 100755 index 0000000..9eb03f8 --- /dev/null +++ b/tests/common.sh @@ -0,0 +1,12 @@ +# +# This file is meant to be sourced from other tests scripts. +# + +if [ -x "$URCU_TEST_TIME_BIN" ]; then + test_time_bin="$URCU_TEST_TIME_BIN" +elif [ -x "/usr/bin/time" ]; then + test_time_bin="/usr/bin/time" +else + test_time_bin="" +fi + diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh index 6c2340d..222069c 100755 --- a/tests/runtests-batch.sh +++ b/tests/runtests-batch.sh @@ -1,8 +1,19 @@ #!/bin/sh +source "./common.sh" + +log_file="runall.detail.log" + +# Check if time bin is defined +if [ -n "$test_time_bin" ]; then + time_command="$test_time_bin -a -o $log_file" +else + time_command="" +fi + #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do for a in test_urcu_gc; do - echo "./${a} $*" | tee -a runall.detail.log - /usr/bin/time -a -o runall.detail.log ./${a} $* + echo "./${a} $*" | tee -a "$log_file" + $time_command ./${a} $* done diff --git a/tests/runtests.sh b/tests/runtests.sh index 79e54df..b3d3dc2 100755 --- a/tests/runtests.sh +++ b/tests/runtests.sh @@ -1,10 +1,21 @@ #!/bin/sh +source "./common.sh" + +log_file="runall.detail.log" + +# Check if time bin is defined +if [ -n "$test_time_bin" ]; then + time_command="$test_time_bin -a -o $log_file" +else + time_command="" +fi + for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ test_rwlock test_perthreadlock test_mutex; do - echo "./${a} $*" | tee -a runall.detail.log - /usr/bin/time -a -o runall.detail.log ./${a} $* + echo "./${a} $*" | tee -a "$log_file" + $time_command ./${a} $* done -- 1.7.1 From mathieu.desnoyers at efficios.com Thu Nov 15 09:10:01 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 15 Nov 2012 09:10:01 -0500 Subject: [lttng-dev] [PATCH urcu v2] runtests: Make path of time binary configurable In-Reply-To: <1352988119-2312-1-git-send-email-simon.marchi@polymtl.ca> References: <1352988119-2312-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121115141001.GA31720@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > I work on a platform that does not come with a time program. This patch > makes it possible to specify the path of the time binary or not use it > if none is available. > > If the URCU_TEST_TIME_BIN environment variable exists and is executable, > it is used. Otherwise it tries with /usr/bin/time, the most common > location. If it is not there, the tests are ran without timing info. > > Signed-off-by: Simon Marchi I have a problem when running make check from userspace rcu tree root with this patch applied: Executing batch RCU test ./runtests-batch.sh: 3: ./runtests-batch.sh: source: not found Thoughts ? Mathieu > --- > > New in v2: removed #!/bin/sh at top of common.sh. > > tests/common.sh | 12 ++++++++++++ > tests/runtests-batch.sh | 15 +++++++++++++-- > tests/runtests.sh | 15 +++++++++++++-- > 3 files changed, 38 insertions(+), 4 deletions(-) > create mode 100755 tests/common.sh > > diff --git a/tests/common.sh b/tests/common.sh > new file mode 100755 > index 0000000..9eb03f8 > --- /dev/null > +++ b/tests/common.sh > @@ -0,0 +1,12 @@ > +# > +# This file is meant to be sourced from other tests scripts. > +# > + > +if [ -x "$URCU_TEST_TIME_BIN" ]; then > + test_time_bin="$URCU_TEST_TIME_BIN" > +elif [ -x "/usr/bin/time" ]; then > + test_time_bin="/usr/bin/time" > +else > + test_time_bin="" > +fi > + > diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh > index 6c2340d..222069c 100755 > --- a/tests/runtests-batch.sh > +++ b/tests/runtests-batch.sh > @@ -1,8 +1,19 @@ > #!/bin/sh > > +source "./common.sh" > + > +log_file="runall.detail.log" > + > +# Check if time bin is defined > +if [ -n "$test_time_bin" ]; then > + time_command="$test_time_bin -a -o $log_file" > +else > + time_command="" > +fi > + > #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do > for a in test_urcu_gc; do > - echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + echo "./${a} $*" | tee -a "$log_file" > + $time_command ./${a} $* > done > > diff --git a/tests/runtests.sh b/tests/runtests.sh > index 79e54df..b3d3dc2 100755 > --- a/tests/runtests.sh > +++ b/tests/runtests.sh > @@ -1,10 +1,21 @@ > #!/bin/sh > > +source "./common.sh" > + > +log_file="runall.detail.log" > + > +# Check if time bin is defined > +if [ -n "$test_time_bin" ]; then > + time_command="$test_time_bin -a -o $log_file" > +else > + time_command="" > +fi > + > for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ > test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ > test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ > test_rwlock test_perthreadlock test_mutex; do > - echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + echo "./${a} $*" | tee -a "$log_file" > + $time_command ./${a} $* > done > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Nov 15 09:32:18 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 15 Nov 2012 09:32:18 -0500 Subject: [lttng-dev] [PATCH urcu v2] runtests: Make path of time binary configurable In-Reply-To: <1352988119-2312-1-git-send-email-simon.marchi@polymtl.ca> References: <1352988119-2312-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121115143218.GA2543@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > I work on a platform that does not come with a time program. This patch > makes it possible to specify the path of the time binary or not use it > if none is available. > > If the URCU_TEST_TIME_BIN environment variable exists and is executable, > it is used. Otherwise it tries with /usr/bin/time, the most common > location. If it is not there, the tests are ran without timing info. > > Signed-off-by: Simon Marchi Merged with edit: commit fce9a534217cc39db50bb546f2521cc4321df197 Author: Simon Marchi Date: Thu Nov 15 09:29:42 2012 -0500 runtests: Make path of time binary configurable I work on a platform that does not come with a time program. This patch makes it possible to specify the path of the time binary or not use it if none is available. If the URCU_TEST_TIME_BIN environment variable exists and is executable, it is used. Otherwise it tries with /usr/bin/time, the most common location. If it is not there, the tests are ran without timing info. [ Edit by Mathieu Desnoyers: use "." instead of "source" (no bash-ism), edit commit about check for emptiness vs definition to match the code. ] Signed-off-by: Simon Marchi Signed-off-by: Mathieu Desnoyers Thanks, Mathieu > --- > > New in v2: removed #!/bin/sh at top of common.sh. > > tests/common.sh | 12 ++++++++++++ > tests/runtests-batch.sh | 15 +++++++++++++-- > tests/runtests.sh | 15 +++++++++++++-- > 3 files changed, 38 insertions(+), 4 deletions(-) > create mode 100755 tests/common.sh > > diff --git a/tests/common.sh b/tests/common.sh > new file mode 100755 > index 0000000..9eb03f8 > --- /dev/null > +++ b/tests/common.sh > @@ -0,0 +1,12 @@ > +# > +# This file is meant to be sourced from other tests scripts. > +# > + > +if [ -x "$URCU_TEST_TIME_BIN" ]; then > + test_time_bin="$URCU_TEST_TIME_BIN" > +elif [ -x "/usr/bin/time" ]; then > + test_time_bin="/usr/bin/time" > +else > + test_time_bin="" > +fi > + > diff --git a/tests/runtests-batch.sh b/tests/runtests-batch.sh > index 6c2340d..222069c 100755 > --- a/tests/runtests-batch.sh > +++ b/tests/runtests-batch.sh > @@ -1,8 +1,19 @@ > #!/bin/sh > > +source "./common.sh" > + > +log_file="runall.detail.log" > + > +# Check if time bin is defined > +if [ -n "$test_time_bin" ]; then > + time_command="$test_time_bin -a -o $log_file" > +else > + time_command="" > +fi > + > #for a in test_urcu_gc test_urcu_gc_mb test_urcu_qsbr_gc; do > for a in test_urcu_gc; do > - echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + echo "./${a} $*" | tee -a "$log_file" > + $time_command ./${a} $* > done > > diff --git a/tests/runtests.sh b/tests/runtests.sh > index 79e54df..b3d3dc2 100755 > --- a/tests/runtests.sh > +++ b/tests/runtests.sh > @@ -1,10 +1,21 @@ > #!/bin/sh > > +source "./common.sh" > + > +log_file="runall.detail.log" > + > +# Check if time bin is defined > +if [ -n "$test_time_bin" ]; then > + time_command="$test_time_bin -a -o $log_file" > +else > + time_command="" > +fi > + > for a in test_urcu_gc test_urcu_signal_gc test_urcu_mb_gc test_urcu_qsbr_gc \ > test_urcu_lgc test_urcu_signal_lgc test_urcu_mb_lgc test_urcu_qsbr_lgc \ > test_urcu test_urcu_signal test_urcu_mb test_urcu_qsbr \ > test_rwlock test_perthreadlock test_mutex; do > - echo "./${a} $*" | tee -a runall.detail.log > - /usr/bin/time -a -o runall.detail.log ./${a} $* > + echo "./${a} $*" | tee -a "$log_file" > + $time_command ./${a} $* > done > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Thu Nov 15 19:24:12 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Thu, 15 Nov 2012 16:24:12 -0800 Subject: [lttng-dev] [PATCH] wfcqueue: Fix lock and unlock functions Message-ID: <20121116002412.GA32432@linux.vnet.ibm.com> The current implementation of cds_wfcq_dequeue_lock() and cds_wfcq_dequeue_unlock() entails mutually assured recursion. Redirect to _cds_wfcq_dequeue_lock() and _cds_wfcq_dequeue_unlock(), respectively. Signed-off-by: Paul E. McKenney diff --git a/wfcqueue.c b/wfcqueue.c index 3474ee0..90b810e 100644 --- a/wfcqueue.c +++ b/wfcqueue.c @@ -57,13 +57,13 @@ void cds_wfcq_enqueue(struct cds_wfcq_head *head, void cds_wfcq_dequeue_lock(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) { - cds_wfcq_dequeue_lock(head, tail); + _cds_wfcq_dequeue_lock(head, tail); } void cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) { - cds_wfcq_dequeue_unlock(head, tail); + _cds_wfcq_dequeue_unlock(head, tail); } struct cds_wfcq_node *cds_wfcq_dequeue_blocking( From mathieu.desnoyers at efficios.com Thu Nov 15 22:08:19 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 15 Nov 2012 22:08:19 -0500 Subject: [lttng-dev] [PATCH] wfcqueue: Fix lock and unlock functions In-Reply-To: <20121116002412.GA32432@linux.vnet.ibm.com> References: <20121116002412.GA32432@linux.vnet.ibm.com> Message-ID: <20121116030819.GB21972@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > The current implementation of cds_wfcq_dequeue_lock() and > cds_wfcq_dequeue_unlock() entails mutually assured recursion. > Redirect to _cds_wfcq_dequeue_lock() and _cds_wfcq_dequeue_unlock(), > respectively. > > Signed-off-by: Paul E. McKenney Good catch !! Merged, thanks! Mathieu > > diff --git a/wfcqueue.c b/wfcqueue.c > index 3474ee0..90b810e 100644 > --- a/wfcqueue.c > +++ b/wfcqueue.c > @@ -57,13 +57,13 @@ void cds_wfcq_enqueue(struct cds_wfcq_head *head, > void cds_wfcq_dequeue_lock(struct cds_wfcq_head *head, > struct cds_wfcq_tail *tail) > { > - cds_wfcq_dequeue_lock(head, tail); > + _cds_wfcq_dequeue_lock(head, tail); > } > > void cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, > struct cds_wfcq_tail *tail) > { > - cds_wfcq_dequeue_unlock(head, tail); > + _cds_wfcq_dequeue_unlock(head, tail); > } > > struct cds_wfcq_node *cds_wfcq_dequeue_blocking( > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Fri Nov 16 10:02:57 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Fri, 16 Nov 2012 16:02:57 +0100 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set Message-ID: <50A655A1.6040804@mentor.com> Hi, embedded users sometimes have to trace to tmpfs (e.g. streaming in not an option due to missing network connectivity). Ramdisks of 16M to 128M size are created and as long as the ram disk does not get full, tracing works fine. Unfortunately if the disk gets full things fall apart: PERROR: Error in file write: No space left on device [in lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] The consumer daemon will not be able to write the metadata channel and therefore the trace data set will be unusable (cannot be read with babeltrace). -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 Is it possible to somehow reserve the file size (fallocate) for metadata so that in case the disk gets full at least the metadata gets written and the resulting trace set is readable with babeltrace ? I wonder if that is possible at all. The consumer daemon doesn't know upfront how much would need to be reserved for metadata, right ? Any ideas ? Thanks, Paul -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From dgoulet at efficios.com Fri Nov 16 10:29:08 2012 From: dgoulet at efficios.com (David Goulet) Date: Fri, 16 Nov 2012 10:29:08 -0500 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A655A1.6040804@mentor.com> References: <50A655A1.6040804@mentor.com> Message-ID: <50A65BC4.3020708@efficios.com> Hi Paul, The problem here would be that metadata can grow arbitrarily over time when let say new events are enabled during tracing or a new lib is dynamically loaded in the application you are tracing. Same goes for the kernel for loaded module or CPU hotplug... To achieve a static size of metadata during the whole life of a tracing session, I guess we need somekind of flag or option set to tell the tracers to just deny new events once started... which from there, we need Mathieu's opinion :) Cheers! David Woegerer, Paul: > Hi, > > embedded users sometimes have to trace to tmpfs (e.g. streaming in not > an option due to missing network connectivity). > > Ramdisks of 16M to 128M size are created and as long as the ram disk > does not get full, tracing works fine. Unfortunately if the disk gets > full things fall apart: > > PERROR: Error in file write: No space left on device [in > lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] > > The consumer daemon will not be able to write the metadata channel and > therefore the trace data set will be unusable (cannot be read with > babeltrace). > > -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata > -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 > -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 > > Is it possible to somehow reserve the file size (fallocate) for metadata > so that in case the disk gets full at least the metadata gets written > and the resulting trace set is readable with babeltrace ? > > I wonder if that is possible at all. The consumer daemon doesn't know > upfront how much would need to be reserved for metadata, right ? > > Any ideas ? > > Thanks, > Paul > > From mathieu.desnoyers at efficios.com Fri Nov 16 10:30:29 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 16 Nov 2012 10:30:29 -0500 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A65BC4.3020708@efficios.com> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> Message-ID: <20121116153029.GB23798@Krystal> * David Goulet (dgoulet at efficios.com) wrote: > Hi Paul, > > The problem here would be that metadata can grow arbitrarily over time > when let say new events are enabled during tracing or a new lib is > dynamically loaded in the application you are tracing. Same goes for the > kernel for loaded module or CPU hotplug... > > To achieve a static size of metadata during the whole life of a tracing > session, I guess we need somekind of flag or option set to tell the > tracers to just deny new events once started... which from there, we > need Mathieu's opinion :) live support will eventually allow to side-track this whole issue by flushing metadata to disk periodically during tracing, Thanks, Mathieu > > Cheers! > David > > Woegerer, Paul: > > Hi, > > > > embedded users sometimes have to trace to tmpfs (e.g. streaming in not > > an option due to missing network connectivity). > > > > Ramdisks of 16M to 128M size are created and as long as the ram disk > > does not get full, tracing works fine. Unfortunately if the disk gets > > full things fall apart: > > > > PERROR: Error in file write: No space left on device [in > > lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] > > > > The consumer daemon will not be able to write the metadata channel and > > therefore the trace data set will be unusable (cannot be read with > > babeltrace). > > > > -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata > > -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 > > -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 > > > > Is it possible to somehow reserve the file size (fallocate) for metadata > > so that in case the disk gets full at least the metadata gets written > > and the resulting trace set is readable with babeltrace ? > > > > I wonder if that is possible at all. The consumer daemon doesn't know > > upfront how much would need to be reserved for metadata, right ? > > > > Any ideas ? > > > > Thanks, > > Paul > > > > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Fri Nov 16 10:39:14 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Fri, 16 Nov 2012 16:39:14 +0100 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <20121116153029.GB23798@Krystal> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> <20121116153029.GB23798@Krystal> Message-ID: <50A65E22.3040203@mentor.com> On 11/16/2012 04:30 PM, Mathieu Desnoyers wrote: > * David Goulet (dgoulet at efficios.com) wrote: >> Hi Paul, >> >> The problem here would be that metadata can grow arbitrarily over time >> when let say new events are enabled during tracing or a new lib is >> dynamically loaded in the application you are tracing. Same goes for the >> kernel for loaded module or CPU hotplug... >> >> To achieve a static size of metadata during the whole life of a tracing >> session, I guess we need somekind of flag or option set to tell the >> tracers to just deny new events once started... which from there, we >> need Mathieu's opinion :) > > live support will eventually allow to side-track this whole issue by > flushing metadata to disk periodically during tracing, Does that mean that the live tracing feature that currently lives in the lttngtop-live branch will go into lttng-tools and babeltrace any time soon ? Thanks Paul > > Thanks, > > Mathieu > >> >> Cheers! >> David >> >> Woegerer, Paul: >>> Hi, >>> >>> embedded users sometimes have to trace to tmpfs (e.g. streaming in not >>> an option due to missing network connectivity). >>> >>> Ramdisks of 16M to 128M size are created and as long as the ram disk >>> does not get full, tracing works fine. Unfortunately if the disk gets >>> full things fall apart: >>> >>> PERROR: Error in file write: No space left on device [in >>> lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] >>> >>> The consumer daemon will not be able to write the metadata channel and >>> therefore the trace data set will be unusable (cannot be read with >>> babeltrace). >>> >>> -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata >>> -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 >>> -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 >>> >>> Is it possible to somehow reserve the file size (fallocate) for metadata >>> so that in case the disk gets full at least the metadata gets written >>> and the resulting trace set is readable with babeltrace ? >>> >>> I wonder if that is possible at all. The consumer daemon doesn't know >>> upfront how much would need to be reserved for metadata, right ? >>> >>> Any ideas ? >>> >>> Thanks, >>> Paul >>> >>> >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From yannick.brosseau at gmail.com Fri Nov 16 10:43:04 2012 From: yannick.brosseau at gmail.com (Yannick Brosseau) Date: Fri, 16 Nov 2012 10:43:04 -0500 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A65BC4.3020708@efficios.com> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> Message-ID: <50A65F08.5060503@gmail.com> It could be interesting to at least reserve the size for the first packet, so we have at least a little bit of information on the trace. On 2012-11-16 10:29, David Goulet wrote: > Hi Paul, > > The problem here would be that metadata can grow arbitrarily over time > when let say new events are enabled during tracing or a new lib is > dynamically loaded in the application you are tracing. Same goes for the > kernel for loaded module or CPU hotplug... > > To achieve a static size of metadata during the whole life of a tracing > session, I guess we need somekind of flag or option set to tell the > tracers to just deny new events once started... which from there, we > need Mathieu's opinion :) > > Cheers! > David > > Woegerer, Paul: >> Hi, >> >> embedded users sometimes have to trace to tmpfs (e.g. streaming in not >> an option due to missing network connectivity). >> >> Ramdisks of 16M to 128M size are created and as long as the ram disk >> does not get full, tracing works fine. Unfortunately if the disk gets >> full things fall apart: >> >> PERROR: Error in file write: No space left on device [in >> lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] >> >> The consumer daemon will not be able to write the metadata channel and >> therefore the trace data set will be unusable (cannot be read with >> babeltrace). >> >> -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata >> -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 >> -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 >> >> Is it possible to somehow reserve the file size (fallocate) for metadata >> so that in case the disk gets full at least the metadata gets written >> and the resulting trace set is readable with babeltrace ? >> >> I wonder if that is possible at all. The consumer daemon doesn't know >> upfront how much would need to be reserved for metadata, right ? >> >> Any ideas ? >> >> Thanks, >> Paul >> >> > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From Paul_Woegerer at mentor.com Fri Nov 16 10:49:35 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Fri, 16 Nov 2012 16:49:35 +0100 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A65F08.5060503@gmail.com> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> <50A65F08.5060503@gmail.com> Message-ID: <50A6608F.1000800@mentor.com> On 11/16/2012 04:43 PM, Yannick Brosseau wrote: > It could be interesting to at least reserve the size for the first > packet, so we have at least a little bit of information on the trace. I tried that with fallocate but unfortunately tmpfs does not seem to support fallocating files :( -- Paul > > On 2012-11-16 10:29, David Goulet wrote: >> Hi Paul, >> >> The problem here would be that metadata can grow arbitrarily over time >> when let say new events are enabled during tracing or a new lib is >> dynamically loaded in the application you are tracing. Same goes for the >> kernel for loaded module or CPU hotplug... >> >> To achieve a static size of metadata during the whole life of a tracing >> session, I guess we need somekind of flag or option set to tell the >> tracers to just deny new events once started... which from there, we >> need Mathieu's opinion :) >> >> Cheers! >> David >> >> Woegerer, Paul: >>> Hi, >>> >>> embedded users sometimes have to trace to tmpfs (e.g. streaming in not >>> an option due to missing network connectivity). >>> >>> Ramdisks of 16M to 128M size are created and as long as the ram disk >>> does not get full, tracing works fine. Unfortunately if the disk gets >>> full things fall apart: >>> >>> PERROR: Error in file write: No space left on device [in >>> lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] >>> >>> The consumer daemon will not be able to write the metadata channel and >>> therefore the trace data set will be unusable (cannot be read with >>> babeltrace). >>> >>> -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata >>> -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 >>> -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 >>> >>> Is it possible to somehow reserve the file size (fallocate) for metadata >>> so that in case the disk gets full at least the metadata gets written >>> and the resulting trace set is readable with babeltrace ? >>> >>> I wonder if that is possible at all. The consumer daemon doesn't know >>> upfront how much would need to be reserved for metadata, right ? >>> >>> Any ideas ? >>> >>> Thanks, >>> Paul >>> >>> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From julien.desfossez at polymtl.ca Fri Nov 16 10:54:28 2012 From: julien.desfossez at polymtl.ca (Julien Desfossez) Date: Fri, 16 Nov 2012 10:54:28 -0500 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A65E22.3040203@mentor.com> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> <20121116153029.GB23798@Krystal> <50A65E22.3040203@mentor.com> Message-ID: <50A661B4.10009@polymtl.ca> On 16/11/12 10:39 AM, Woegerer, Paul wrote: > On 11/16/2012 04:30 PM, Mathieu Desnoyers wrote: >> * David Goulet (dgoulet at efficios.com) wrote: >>> Hi Paul, >>> >>> The problem here would be that metadata can grow arbitrarily over time >>> when let say new events are enabled during tracing or a new lib is >>> dynamically loaded in the application you are tracing. Same goes for the >>> kernel for loaded module or CPU hotplug... >>> >>> To achieve a static size of metadata during the whole life of a tracing >>> session, I guess we need somekind of flag or option set to tell the >>> tracers to just deny new events once started... which from there, we >>> need Mathieu's opinion :) >> >> live support will eventually allow to side-track this whole issue by >> flushing metadata to disk periodically during tracing, > > Does that mean that the live tracing feature that currently lives in the > lttngtop-live branch will go into lttng-tools and babeltrace any time soon ? The main change of lttng-tools 2.2 is the live tracing feature. The way it is implemented in the lttngtop-live branch is more a proof-of-concept, we will be starting the clean implementation discussions here as soon as we have lttng-tools 2.1 released (which should be around the end of this month). In the mean time, to solve the problem you are currently experiencing, you could manually add a flush on the metadata channel after the session is started to make sure it is written on disk quickly (that's what is done in lttngtop-live at the beginning). Of course like David said, if you have new events/applications enabled during tracing, the metadata needs to be flushed again. Thanks, Julien > > Thanks > Paul > >> >> Thanks, >> >> Mathieu >> >>> >>> Cheers! >>> David >>> >>> Woegerer, Paul: >>>> Hi, >>>> >>>> embedded users sometimes have to trace to tmpfs (e.g. streaming in not >>>> an option due to missing network connectivity). >>>> >>>> Ramdisks of 16M to 128M size are created and as long as the ram disk >>>> does not get full, tracing works fine. Unfortunately if the disk gets >>>> full things fall apart: >>>> >>>> PERROR: Error in file write: No space left on device [in >>>> lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] >>>> >>>> The consumer daemon will not be able to write the metadata channel and >>>> therefore the trace data set will be unusable (cannot be read with >>>> babeltrace). >>>> >>>> -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata >>>> -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 >>>> -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 >>>> >>>> Is it possible to somehow reserve the file size (fallocate) for metadata >>>> so that in case the disk gets full at least the metadata gets written >>>> and the resulting trace set is readable with babeltrace ? >>>> >>>> I wonder if that is possible at all. The consumer daemon doesn't know >>>> upfront how much would need to be reserved for metadata, right ? >>>> >>>> Any ideas ? >>>> >>>> Thanks, >>>> Paul >>>> >>>> >>> >>> _______________________________________________ >>> lttng-dev mailing list >>> lttng-dev at lists.lttng.org >>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev >> > > From Paul_Woegerer at mentor.com Fri Nov 16 10:59:02 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Fri, 16 Nov 2012 16:59:02 +0100 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A661B4.10009@polymtl.ca> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> <20121116153029.GB23798@Krystal> <50A65E22.3040203@mentor.com> <50A661B4.10009@polymtl.ca> Message-ID: <50A662C6.5050507@mentor.com> On 11/16/2012 04:54 PM, Julien Desfossez wrote: > On 16/11/12 10:39 AM, Woegerer, Paul wrote: >> Does that mean that the live tracing feature that currently lives in the >> lttngtop-live branch will go into lttng-tools and babeltrace any time soon ? > > The main change of lttng-tools 2.2 is the live tracing feature. > The way it is implemented in the lttngtop-live branch is more a > proof-of-concept, we will be starting the clean implementation > discussions here as soon as we have lttng-tools 2.1 released (which > should be around the end of this month). > > In the mean time, to solve the problem you are currently experiencing, > you could manually add a flush on the metadata channel after the session > is started to make sure it is written on disk quickly (that's what is > done in lttngtop-live at the beginning). Of course like David said, if I will try that. Thanks ! -- Paul > you have new events/applications enabled during tracing, the metadata > needs to be flushed again. > > Thanks, > > Julien > > >> >> Thanks >> Paul >> >>> >>> Thanks, >>> >>> Mathieu >>> >>>> >>>> Cheers! >>>> David >>>> >>>> Woegerer, Paul: >>>>> Hi, >>>>> >>>>> embedded users sometimes have to trace to tmpfs (e.g. streaming in not >>>>> an option due to missing network connectivity). >>>>> >>>>> Ramdisks of 16M to 128M size are created and as long as the ram disk >>>>> does not get full, tracing works fine. Unfortunately if the disk gets >>>>> full things fall apart: >>>>> >>>>> PERROR: Error in file write: No space left on device [in >>>>> lttng_consumer_on_read_subbuffer_mmap() at consumer.c:1367] >>>>> >>>>> The consumer daemon will not be able to write the metadata channel and >>>>> therefore the trace data set will be unusable (cannot be read with >>>>> babeltrace). >>>>> >>>>> -rwxrwxrwx 1 testuser users 0 Nov 16 11:22 metadata >>>>> -rwxrwxrwx 1 testuser users 15728640 Nov 16 11:22 myevents_0 >>>>> -rwxrwxrwx 1 testuser users 4096 Nov 16 11:22 myevents_1 >>>>> >>>>> Is it possible to somehow reserve the file size (fallocate) for metadata >>>>> so that in case the disk gets full at least the metadata gets written >>>>> and the resulting trace set is readable with babeltrace ? >>>>> >>>>> I wonder if that is possible at all. The consumer daemon doesn't know >>>>> upfront how much would need to be reserved for metadata, right ? >>>>> >>>>> Any ideas ? >>>>> >>>>> Thanks, >>>>> Paul >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> lttng-dev mailing list >>>> lttng-dev at lists.lttng.org >>>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev >>> >> >> -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:39 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:39 -0500 Subject: [lttng-dev] userspace rcu flavor improvements Message-ID: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Here are a couple of improvements for all userspace RCU flavors. Many thanks to Alan Stern for his suggestions. Patch 8/8 is only done for qsbr so far, and proposed as RFC. I'd like to try and benchmark other approaches to concurrent grace periods too. Feedback is welcome, Thanks, Mathieu From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:40 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:40 -0500 Subject: [lttng-dev] [PATCH 1/8] urcu-qsbr: improve 2-phase wait scheme In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-2-git-send-email-mathieu.desnoyers@efficios.com> In the single-bit, 2-phase grace period scheme, all we need to do is to observe each reader going through a quiescent state while we are in the grace period. We therefore only need to perform one global counter update, surrounded by 2 iterations on readers to observe change in their snapshot. We can therefore remove the first counter update (prior to the first iteration on readers): it was useless and was only slowing down the grace period. Suggested-by: Alan Stern CC: Paul E. McKenney CC: Lai Jiangshan Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 92 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index c6a1b18..eb167d1 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -116,38 +116,16 @@ static void wait_gp(void) NULL, NULL, 0); } -static void update_counter_and_wait(void) +static void wait_for_readers(void) { CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; -#if (CAA_BITS_PER_LONG < 64) - /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR); -#else /* !(CAA_BITS_PER_LONG < 64) */ - /* Increment current G.P. */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR); -#endif /* !(CAA_BITS_PER_LONG < 64) */ - - /* - * Must commit rcu_gp_ctr update to memory before waiting for - * quiescent state. Failure to do so could result in the writer - * waiting forever while new readers are always accessing data - * (no progress). Enforce compiler-order of store to rcu_gp_ctr - * before load URCU_TLS(rcu_reader).ctr. - */ - cmm_barrier(); - - /* - * Adding a cmm_smp_mb() which is _not_ formally required, but makes the - * model easier to understand. It does not have a big performance impact - * anyway, given this is the write-side. - */ - cmm_smp_mb(); - /* - * Wait for each thread rcu_reader_qs_gp count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr to either + * indicate quiescence (offline), or for them to observe the + * current rcu_gp_ctr value. */ for (;;) { wait_loops++; @@ -223,17 +201,17 @@ void synchronize_rcu(void) goto out; /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe original parity or be quiescent. */ - update_counter_and_wait(); /* 0 -> 1, wait readers in parity 0 */ + wait_for_readers(); /* - * Must finish waiting for quiescent state for parity 0 before - * committing next rcu_gp_ctr update to memory. Failure to - * do so could result in the writer waiting forever while new + * Must finish waiting for quiescent state for original parity + * before committing next rcu_gp_ctr update to memory. Failure + * to do so could result in the writer waiting forever while new * readers are always accessing data (no progress). Enforce - * compiler-order of load URCU_TLS(rcu_reader).ctr before store to - * rcu_gp_ctr. + * compiler-order of load URCU_TLS(rcu_reader).ctr before store + * to rcu_gp_ctr. */ cmm_barrier(); @@ -244,10 +222,29 @@ void synchronize_rcu(void) */ cmm_smp_mb(); + /* Switch parity: 0 -> 1, 1 -> 0 */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR); + /* - * Wait for previous parity to be empty of readers. + * Must commit rcu_gp_ctr update to memory before waiting for + * quiescent state. Failure to do so could result in the writer + * waiting forever while new readers are always accessing data + * (no progress). Enforce compiler-order of store to rcu_gp_ctr + * before load URCU_TLS(rcu_reader).ctr. */ - update_counter_and_wait(); /* 1 -> 0, wait readers in parity 1 */ + cmm_barrier(); + + /* + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + + /* + * Wait for readers to observe new parity or be quiescent. + */ + wait_for_readers(); out: mutex_unlock(&rcu_gp_lock); @@ -280,7 +277,30 @@ void synchronize_rcu(void) mutex_lock(&rcu_gp_lock); if (cds_list_empty(®istry)) goto out; - update_counter_and_wait(); + + /* Increment current G.P. */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR); + + /* + * Must commit rcu_gp_ctr update to memory before waiting for + * quiescent state. Failure to do so could result in the writer + * waiting forever while new readers are always accessing data + * (no progress). Enforce compiler-order of store to rcu_gp_ctr + * before load URCU_TLS(rcu_reader).ctr. + */ + cmm_barrier(); + + /* + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + + /* + * Wait for readers to observe new count of be quiescent. + */ + wait_for_readers(); out: mutex_unlock(&rcu_gp_lock); -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:41 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:41 -0500 Subject: [lttng-dev] [PATCH 2/8] urcu-mb/signal/membarrier: improve 2-phase wait scheme In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-3-git-send-email-mathieu.desnoyers@efficios.com> In the single-bit, 2-phase grace period scheme, all we need to do is to observe each reader going through a quiescent state while we are in the grace period. We therefore only need to perform one global counter update, surrounded by 2 iterations on readers to observe change in their snapshot. We can therefore remove the first counter update (prior to the first iteration on readers): it was useless and was only slowing down the grace period. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu.c | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/urcu.c b/urcu.c index c421846..2d5c510 100644 --- a/urcu.c +++ b/urcu.c @@ -215,33 +215,16 @@ static void wait_gp(void) NULL, NULL, 0); } -static void update_counter_and_wait(void) +static void wait_for_readers(void) { CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; - /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); - - /* - * Must commit rcu_gp_ctr update to memory before waiting for quiescent - * state. Failure to do so could result in the writer waiting forever - * while new readers are always accessing data (no progress). Enforce - * compiler-order of store to rcu_gp_ctr before load rcu_reader ctr. - */ - cmm_barrier(); - - /* - * - * Adding a cmm_smp_mb() which is _not_ formally required, but makes the - * model easier to understand. It does not have a big performance impact - * anyway, given this is the write-side. - */ - cmm_smp_mb(); - /* - * Wait for each thread URCU_TLS(rcu_reader).ctr count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr to either + * indicate quiescence (not nested), or observe the current + * rcu_gp_ctr value. */ for (;;) { wait_loops++; @@ -316,12 +299,12 @@ void synchronize_rcu(void) smp_mb_master(RCU_MB_GROUP); /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe original parity or be quiescent. */ - update_counter_and_wait(); /* 0 -> 1, wait readers in parity 0 */ + wait_for_readers(); /* - * Must finish waiting for quiescent state for parity 0 before + * Must finish waiting for quiescent state for original parity before * committing next rcu_gp_ctr update to memory. Failure to do so could * result in the writer waiting forever while new readers are always * accessing data (no progress). Enforce compiler-order of load @@ -336,10 +319,29 @@ void synchronize_rcu(void) */ cmm_smp_mb(); + /* Switch parity: 0 -> 1, 1 -> 0 */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); + + /* + * Must commit rcu_gp_ctr update to memory before waiting for quiescent + * state. Failure to do so could result in the writer waiting forever + * while new readers are always accessing data (no progress). Enforce + * compiler-order of store to rcu_gp_ctr before load rcu_reader ctr. + */ + cmm_barrier(); + + /* + * + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe new parity or be quiescent. */ - update_counter_and_wait(); /* 1 -> 0, wait readers in parity 1 */ + wait_for_readers(); /* Finish waiting for reader threads before letting the old ptr being * freed. Must be done within rcu_gp_lock because it iterates on reader -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:42 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:42 -0500 Subject: [lttng-dev] [PATCH 3/8] urcu-bp: improve 2-phase wait scheme In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-4-git-send-email-mathieu.desnoyers@efficios.com> In the single-bit, 2-phase grace period scheme, all we need to do is to observe each reader going through a quiescent state while we are in the grace period. We therefore only need to perform one global counter update, surrounded by 2 iterations on readers to observe change in their snapshot. We can therefore remove the first counter update (prior to the first iteration on readers): it was useless and was only slowing down the grace period. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-bp.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/urcu-bp.c b/urcu-bp.c index b07a1bb..4b3cf01 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -164,31 +164,16 @@ static void mutex_unlock(pthread_mutex_t *mutex) urcu_die(ret); } -static void update_counter_and_wait(void) +static void wait_for_readers(void) { CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; - /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); - - /* - * Must commit qparity update to memory before waiting for other parity - * quiescent state. Failure to do so could result in the writer waiting - * forever while new readers are always accessing data (no progress). - * Ensured by CMM_STORE_SHARED and CMM_LOAD_SHARED. - */ - - /* - * Adding a cmm_smp_mb() which is _not_ formally required, but makes the - * model easier to understand. It does not have a big performance impact - * anyway, given this is the write-side. - */ - cmm_smp_mb(); - /* - * Wait for each thread rcu_reader.ctr count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr to either + * indicate quiescence (not nested), or observe the current + * rcu_gp_ctr value. */ for (;;) { wait_loops++; @@ -234,9 +219,26 @@ void synchronize_rcu(void) rcu_gc_registry(); /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe original parity or be quiescent. + */ + wait_for_readers(); + + /* + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + + /* Switch parity: 0 -> 1, 1 -> 0 */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); + + /* + * Must commit qparity update to memory before waiting for other parity + * quiescent state. Failure to do so could result in the writer waiting + * forever while new readers are always accessing data (no progress). + * Ensured by CMM_STORE_SHARED and CMM_LOAD_SHARED. */ - update_counter_and_wait(); /* 0 -> 1, wait readers in parity 0 */ /* * Adding a cmm_smp_mb() which is _not_ formally required, but makes the @@ -246,9 +248,9 @@ void synchronize_rcu(void) cmm_smp_mb(); /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe new parity or be quiescent. */ - update_counter_and_wait(); /* 1 -> 0, wait readers in parity 1 */ + wait_for_readers(); /* * Finish waiting for reader threads before letting the old ptr being -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:43 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:43 -0500 Subject: [lttng-dev] [PATCH 4/8] urcu-qsbr: move offline threads to separate list In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-5-git-send-email-mathieu.desnoyers@efficios.com> Accelerate 2-phase grace period by not having to iterate on offline threads twice. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 54 ++++++++++++++++++++++++++++++++++++----------- urcu/static/urcu-qsbr.h | 14 ++++++++++-- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index eb167d1..5b341b5 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -116,9 +116,10 @@ static void wait_gp(void) NULL, NULL, 0); } -static void wait_for_readers(void) +static void wait_for_readers(struct cds_list_head *input_readers, + struct cds_list_head *cur_snap_readers, + struct cds_list_head *qsreaders) { - CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; @@ -136,18 +137,36 @@ static void wait_for_readers(void) * reads them in the opposite order). */ cmm_smp_wmb(); - cds_list_for_each_entry(index, ®istry, node) { + cds_list_for_each_entry(index, input_readers, node) { _CMM_STORE_SHARED(index->waiting, 1); } /* Write futex before read reader_gp */ cmm_smp_mb(); } - cds_list_for_each_entry_safe(index, tmp, ®istry, node) { - if (!rcu_gp_ongoing(&index->ctr)) - cds_list_move(&index->node, &qsreaders); + cds_list_for_each_entry_safe(index, tmp, input_readers, node) { + switch (rcu_reader_state(&index->ctr)) { + case RCU_READER_ACTIVE_CURRENT: + if (cur_snap_readers) { + cds_list_move(&index->node, + cur_snap_readers); + break; + } + /* Fall-through */ + case RCU_READER_INACTIVE: + cds_list_move(&index->node, qsreaders); + break; + case RCU_READER_ACTIVE_OLD: + /* + * Old snapshot. Leaving node in + * input_readers will make us busy-loop + * until the snapshot becomes current or + * the reader becomes inactive. + */ + break; + } } - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) { /* Read reader_gp before write futex */ cmm_smp_mb(); @@ -166,8 +185,6 @@ static void wait_for_readers(void) } } } - /* put back the reader list in the registry */ - cds_list_splice(&qsreaders, ®istry); } /* @@ -178,6 +195,8 @@ static void wait_for_readers(void) #if (CAA_BITS_PER_LONG < 64) void synchronize_rcu(void) { + CDS_LIST_HEAD(cur_snap_readers); + CDS_LIST_HEAD(qsreaders); unsigned long was_online; was_online = URCU_TLS(rcu_reader).ctr; @@ -203,7 +222,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe original parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders); /* * Must finish waiting for quiescent state for original parity @@ -244,7 +263,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); out: mutex_unlock(&rcu_gp_lock); @@ -260,6 +284,7 @@ out: #else /* !(CAA_BITS_PER_LONG < 64) */ void synchronize_rcu(void) { + CDS_LIST_HEAD(qsreaders); unsigned long was_online; was_online = URCU_TLS(rcu_reader).ctr; @@ -300,7 +325,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new count of be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); out: mutex_unlock(&rcu_gp_lock); diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h index f314956..f6e5580 100644 --- a/urcu/static/urcu-qsbr.h +++ b/urcu/static/urcu-qsbr.h @@ -62,6 +62,12 @@ extern "C" { #define rcu_assert(args...) #endif +enum rcu_state { + RCU_READER_ACTIVE_CURRENT, + RCU_READER_ACTIVE_OLD, + RCU_READER_INACTIVE, +}; + #ifdef DEBUG_YIELD #include #include @@ -149,12 +155,16 @@ static inline void wake_up_gp(void) } } -static inline int rcu_gp_ongoing(unsigned long *ctr) +static inline enum rcu_state rcu_reader_state(unsigned long *ctr) { unsigned long v; v = CMM_LOAD_SHARED(*ctr); - return v && (v != rcu_gp_ctr); + if (!v) + return RCU_READER_INACTIVE; + if (v == rcu_gp_ctr) + return RCU_READER_ACTIVE_CURRENT; + return RCU_READER_ACTIVE_OLD; } /* -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:44 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:44 -0500 Subject: [lttng-dev] [PATCH 5/8] urcu-mb/signal/membarrier: move quiescent threads to separate list In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-6-git-send-email-mathieu.desnoyers@efficios.com> Accelerate 2-phase grace period by not having to iterate twice on threads not nested within a RCU read-side lock. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu.c | 47 ++++++++++++++++++++++++++++++++++++----------- urcu/static/urcu.h | 15 ++++++++++++--- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/urcu.c b/urcu.c index 2d5c510..c692db9 100644 --- a/urcu.c +++ b/urcu.c @@ -215,9 +215,10 @@ static void wait_gp(void) NULL, NULL, 0); } -static void wait_for_readers(void) +static void wait_for_readers(struct cds_list_head *input_readers, + struct cds_list_head *cur_snap_readers, + struct cds_list_head *qsreaders) { - CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; @@ -234,13 +235,31 @@ static void wait_for_readers(void) smp_mb_master(RCU_MB_GROUP); } - cds_list_for_each_entry_safe(index, tmp, ®istry, node) { - if (!rcu_gp_ongoing(&index->ctr)) - cds_list_move(&index->node, &qsreaders); + cds_list_for_each_entry_safe(index, tmp, input_readers, node) { + switch (rcu_reader_state(&index->ctr)) { + case RCU_READER_ACTIVE_CURRENT: + if (cur_snap_readers) { + cds_list_move(&index->node, + cur_snap_readers); + break; + } + /* Fall-through */ + case RCU_READER_INACTIVE: + cds_list_move(&index->node, qsreaders); + break; + case RCU_READER_ACTIVE_OLD: + /* + * Old snapshot. Leaving node in + * input_readers will make us busy-loop + * until the snapshot becomes current or + * the reader becomes inactive. + */ + break; + } } #ifndef HAS_INCOHERENT_CACHES - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { /* Read reader_gp before write futex */ smp_mb_master(RCU_MB_GROUP); @@ -259,7 +278,7 @@ static void wait_for_readers(void) * URCU_TLS(rcu_reader).ctr update to memory if we wait * for too long. */ - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { /* Read reader_gp before write futex */ smp_mb_master(RCU_MB_GROUP); @@ -281,12 +300,13 @@ static void wait_for_readers(void) } #endif /* #else #ifndef HAS_INCOHERENT_CACHES */ } - /* put back the reader list in the registry */ - cds_list_splice(&qsreaders, ®istry); } void synchronize_rcu(void) { + CDS_LIST_HEAD(cur_snap_readers); + CDS_LIST_HEAD(qsreaders); + mutex_lock(&rcu_gp_lock); if (cds_list_empty(®istry)) @@ -301,7 +321,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe original parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders); /* * Must finish waiting for quiescent state for original parity before @@ -341,7 +361,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); /* Finish waiting for reader threads before letting the old ptr being * freed. Must be done within rcu_gp_lock because it iterates on reader diff --git a/urcu/static/urcu.h b/urcu/static/urcu.h index f32f300..973826a 100644 --- a/urcu/static/urcu.h +++ b/urcu/static/urcu.h @@ -96,6 +96,12 @@ extern "C" { #define SIGRCU SIGUSR1 #endif +enum rcu_state { + RCU_READER_ACTIVE_CURRENT, + RCU_READER_ACTIVE_OLD, + RCU_READER_INACTIVE, +}; + #ifdef DEBUG_RCU #define rcu_assert(args...) assert(args) #else @@ -239,7 +245,7 @@ static inline void wake_up_gp(void) } } -static inline int rcu_gp_ongoing(unsigned long *ctr) +static inline enum rcu_state rcu_reader_state(unsigned long *ctr) { unsigned long v; @@ -248,8 +254,11 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) * to insure consistency. */ v = CMM_LOAD_SHARED(*ctr); - return (v & RCU_GP_CTR_NEST_MASK) && - ((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE); + if (!(v & RCU_GP_CTR_NEST_MASK)) + return RCU_READER_INACTIVE; + if (!((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE)) + return RCU_READER_ACTIVE_CURRENT; + return RCU_READER_ACTIVE_OLD; } /* -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:45 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:45 -0500 Subject: [lttng-dev] [PATCH 6/8] urcu-bp: move quiescent threads to separate list In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-7-git-send-email-mathieu.desnoyers@efficios.com> Accelerate 2-phase grace period by not having to iterate twice on threads not within RCU read-side critical section. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-bp.c | 46 +++++++++++++++++++++++++++++++++++----------- urcu.c | 2 +- urcu/static/urcu-bp.h | 29 +++++++++++++++++++---------- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/urcu-bp.c b/urcu-bp.c index 4b3cf01..f99c0e5 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -115,7 +115,7 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); * Also has a RCU_GP_COUNT of 1, to accelerate the reader fast path. * Written to only by writer with mutex taken. Read by both writer and readers. */ -long rcu_gp_ctr = RCU_GP_COUNT; +unsigned long rcu_gp_ctr = RCU_GP_COUNT; /* * Pointer to registry elements. Written to only by each individual reader. Read @@ -164,9 +164,10 @@ static void mutex_unlock(pthread_mutex_t *mutex) urcu_die(ret); } -static void wait_for_readers(void) +static void wait_for_readers(struct cds_list_head *input_readers, + struct cds_list_head *cur_snap_readers, + struct cds_list_head *qsreaders) { - CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; @@ -177,12 +178,30 @@ static void wait_for_readers(void) */ for (;;) { wait_loops++; - cds_list_for_each_entry_safe(index, tmp, ®istry, node) { - if (!rcu_old_gp_ongoing(&index->ctr)) - cds_list_move(&index->node, &qsreaders); + cds_list_for_each_entry_safe(index, tmp, input_readers, node) { + switch (rcu_reader_state(&index->ctr)) { + case RCU_READER_ACTIVE_CURRENT: + if (cur_snap_readers) { + cds_list_move(&index->node, + cur_snap_readers); + break; + } + /* Fall-through */ + case RCU_READER_INACTIVE: + cds_list_move(&index->node, qsreaders); + break; + case RCU_READER_ACTIVE_OLD: + /* + * Old snapshot. Leaving node in + * input_readers will make us busy-loop + * until the snapshot becomes current or + * the reader becomes inactive. + */ + break; + } } - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { break; } else { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) @@ -191,12 +210,12 @@ static void wait_for_readers(void) caa_cpu_relax(); } } - /* put back the reader list in the registry */ - cds_list_splice(&qsreaders, ®istry); } void synchronize_rcu(void) { + CDS_LIST_HEAD(cur_snap_readers); + CDS_LIST_HEAD(qsreaders); sigset_t newmask, oldmask; int ret; @@ -221,7 +240,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe original parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders); /* * Adding a cmm_smp_mb() which is _not_ formally required, but makes the @@ -250,7 +269,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); /* * Finish waiting for reader threads before letting the old ptr being diff --git a/urcu.c b/urcu.c index c692db9..e6ff0f3 100644 --- a/urcu.c +++ b/urcu.c @@ -361,7 +361,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(®istry, NULL, &qsreaders); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders); /* * Put quiescent reader list back into registry. diff --git a/urcu/static/urcu-bp.h b/urcu/static/urcu-bp.h index c52a688..c7f5326 100644 --- a/urcu/static/urcu-bp.h +++ b/urcu/static/urcu-bp.h @@ -58,6 +58,12 @@ extern "C" { #define rcu_assert(args...) #endif +enum rcu_state { + RCU_READER_ACTIVE_CURRENT, + RCU_READER_ACTIVE_OLD, + RCU_READER_INACTIVE, +}; + #ifdef DEBUG_YIELD #include #include @@ -129,11 +135,11 @@ extern void rcu_bp_register(void); * Using a int rather than a char to eliminate false register dependencies * causing stalls on some architectures. */ -extern long rcu_gp_ctr; +extern unsigned long rcu_gp_ctr; struct rcu_reader { /* Data used by both reader and synchronize_rcu() */ - long ctr; + unsigned long ctr; /* Data used for registry */ struct cds_list_head node __attribute__((aligned(CAA_CACHE_LINE_SIZE))); pthread_t tid; @@ -147,19 +153,22 @@ struct rcu_reader { */ extern DECLARE_URCU_TLS(struct rcu_reader *, rcu_reader); -static inline int rcu_old_gp_ongoing(long *value) +static inline enum rcu_state rcu_reader_state(unsigned long *ctr) { - long v; + unsigned long v; - if (value == NULL) - return 0; + if (ctr == NULL) + return RCU_READER_INACTIVE; /* * Make sure both tests below are done on the same version of *value * to insure consistency. */ - v = CMM_LOAD_SHARED(*value); - return (v & RCU_GP_CTR_NEST_MASK) && - ((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE); + v = CMM_LOAD_SHARED(*ctr); + if (!(v & RCU_GP_CTR_NEST_MASK)) + return RCU_READER_INACTIVE; + if (!((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE)) + return RCU_READER_ACTIVE_CURRENT; + return RCU_READER_ACTIVE_OLD; } /* @@ -190,7 +199,7 @@ static inline void _rcu_read_lock_update(unsigned long tmp) */ static inline void _rcu_read_lock(void) { - long tmp; + unsigned long tmp; if (caa_unlikely(!URCU_TLS(rcu_reader))) rcu_bp_register(); /* If not yet registered. */ -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:46 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:46 -0500 Subject: [lttng-dev] [PATCH 7/8] tests: use standard malloc/free for synchronize_rcu() In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-8-git-send-email-mathieu.desnoyers@efficios.com> Allows removing mutex from tests, which allow testing scalability of concurrent synchronize_rcu() executions. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- tests/test_urcu.c | 60 ++++++++--------------------------------------- tests/test_urcu_bp.c | 59 +++++++--------------------------------------- tests/test_urcu_qsbr.c | 61 ++++++++---------------------------------------- 3 files changed, 29 insertions(+), 151 deletions(-) diff --git a/tests/test_urcu.c b/tests/test_urcu.c index 6463d67..87972aa 100644 --- a/tests/test_urcu.c +++ b/tests/test_urcu.c @@ -66,15 +66,11 @@ static inline pid_t gettid(void) #endif #include -struct test_array { - int a; -}; - static volatile int test_go, test_stop; static unsigned long wdelay; -static struct test_array *test_rcu_pointer; +static int *test_rcu_pointer; static unsigned long duration; @@ -185,43 +181,10 @@ void rcu_copy_mutex_unlock(void) } } -/* - * malloc/free are reusing memory areas too quickly, which does not let us - * test races appropriately. Use a large circular array for allocations. - * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across - * both alloc and free, which insures we never run over our tail. - */ -#define ARRAY_SIZE (1048576 * nr_writers) -#define ARRAY_POISON 0xDEADBEEF -static int array_index; -static struct test_array *test_array; - -static struct test_array *test_array_alloc(void) -{ - struct test_array *ret; - int index; - - index = array_index % ARRAY_SIZE; - assert(test_array[index].a == ARRAY_POISON || - test_array[index].a == 0); - ret = &test_array[index]; - array_index++; - if (array_index == ARRAY_SIZE) - array_index = 0; - return ret; -} - -static void test_array_free(struct test_array *ptr) -{ - if (!ptr) - return; - ptr->a = ARRAY_POISON; -} - void *thr_reader(void *_count) { unsigned long long *count = _count; - struct test_array *local_ptr; + int *local_ptr; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), @@ -241,7 +204,7 @@ void *thr_reader(void *_count) local_ptr = rcu_dereference(test_rcu_pointer); rcu_debug_yield_read(); if (local_ptr) - assert(local_ptr->a == 8); + assert(*local_ptr == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); @@ -267,7 +230,7 @@ void *thr_reader(void *_count) void *thr_writer(void *_count) { unsigned long long *count = _count; - struct test_array *new, *old; + int *new, *old; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), @@ -281,17 +244,16 @@ void *thr_writer(void *_count) cmm_smp_mb(); for (;;) { - rcu_copy_mutex_lock(); - new = test_array_alloc(); - new->a = 8; + new = malloc(sizeof(int)); + assert(new); + *new = 8; old = rcu_xchg_pointer(&test_rcu_pointer, new); if (caa_unlikely(wduration)) loop_sleep(wduration); synchronize_rcu(); if (old) - old->a = 0; - test_array_free(old); - rcu_copy_mutex_unlock(); + *old = 0; + free(old); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; @@ -409,7 +371,6 @@ int main(int argc, char **argv) "main", (unsigned long) pthread_self(), (unsigned long)gettid()); - test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); @@ -459,8 +420,7 @@ int main(int argc, char **argv) argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); - test_array_free(test_rcu_pointer); - free(test_array); + free(test_rcu_pointer); free(tid_reader); free(tid_writer); free(count_reader); diff --git a/tests/test_urcu_bp.c b/tests/test_urcu_bp.c index 7902388..58afe90 100644 --- a/tests/test_urcu_bp.c +++ b/tests/test_urcu_bp.c @@ -66,15 +66,11 @@ static inline pid_t gettid(void) #endif #include -struct test_array { - int a; -}; - static volatile int test_go, test_stop; static unsigned long wdelay; -static struct test_array *test_rcu_pointer; +static int *test_rcu_pointer; static unsigned long duration; @@ -185,43 +181,10 @@ void rcu_copy_mutex_unlock(void) } } -/* - * malloc/free are reusing memory areas too quickly, which does not let us - * test races appropriately. Use a large circular array for allocations. - * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across - * both alloc and free, which insures we never run over our tail. - */ -#define ARRAY_SIZE (1048576 * nr_writers) -#define ARRAY_POISON 0xDEADBEEF -static int array_index; -static struct test_array *test_array; - -static struct test_array *test_array_alloc(void) -{ - struct test_array *ret; - int index; - - index = array_index % ARRAY_SIZE; - assert(test_array[index].a == ARRAY_POISON || - test_array[index].a == 0); - ret = &test_array[index]; - array_index++; - if (array_index == ARRAY_SIZE) - array_index = 0; - return ret; -} - -static void test_array_free(struct test_array *ptr) -{ - if (!ptr) - return; - ptr->a = ARRAY_POISON; -} - void *thr_reader(void *_count) { unsigned long long *count = _count; - struct test_array *local_ptr; + int *local_ptr; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), @@ -241,7 +204,7 @@ void *thr_reader(void *_count) local_ptr = rcu_dereference(test_rcu_pointer); rcu_debug_yield_read(); if (local_ptr) - assert(local_ptr->a == 8); + assert(*local_ptr == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); @@ -263,7 +226,7 @@ void *thr_reader(void *_count) void *thr_writer(void *_count) { unsigned long long *count = _count; - struct test_array *new, *old; + int *new, *old; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), @@ -277,17 +240,15 @@ void *thr_writer(void *_count) cmm_smp_mb(); for (;;) { - rcu_copy_mutex_lock(); - new = test_array_alloc(); - new->a = 8; + new = malloc(sizeof(int)); + *new = 8; old = rcu_xchg_pointer(&test_rcu_pointer, new); if (caa_unlikely(wduration)) loop_sleep(wduration); synchronize_rcu(); if (old) - old->a = 0; - test_array_free(old); - rcu_copy_mutex_unlock(); + *old = 0; + free(old); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; @@ -405,7 +366,6 @@ int main(int argc, char **argv) "main", (unsigned long) pthread_self(), (unsigned long) gettid()); - test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); @@ -455,8 +415,7 @@ int main(int argc, char **argv) argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); - test_array_free(test_rcu_pointer); - free(test_array); + free(test_rcu_pointer); free(tid_reader); free(tid_writer); free(count_reader); diff --git a/tests/test_urcu_qsbr.c b/tests/test_urcu_qsbr.c index da26b77..d5d893c 100644 --- a/tests/test_urcu_qsbr.c +++ b/tests/test_urcu_qsbr.c @@ -66,15 +66,11 @@ static inline pid_t gettid(void) #endif #include "urcu-qsbr.h" -struct test_array { - int a; -}; - static volatile int test_go, test_stop; static unsigned long wdelay; -static struct test_array *test_rcu_pointer; +static int *test_rcu_pointer; static unsigned long duration; @@ -184,43 +180,10 @@ void rcu_copy_mutex_unlock(void) } } -/* - * malloc/free are reusing memory areas too quickly, which does not let us - * test races appropriately. Use a large circular array for allocations. - * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across - * both alloc and free, which insures we never run over our tail. - */ -#define ARRAY_SIZE (1048576 * nr_writers) -#define ARRAY_POISON 0xDEADBEEF -static int array_index; -static struct test_array *test_array; - -static struct test_array *test_array_alloc(void) -{ - struct test_array *ret; - int index; - - index = array_index % ARRAY_SIZE; - assert(test_array[index].a == ARRAY_POISON || - test_array[index].a == 0); - ret = &test_array[index]; - array_index++; - if (array_index == ARRAY_SIZE) - array_index = 0; - return ret; -} - -static void test_array_free(struct test_array *ptr) -{ - if (!ptr) - return; - ptr->a = ARRAY_POISON; -} - void *thr_reader(void *_count) { unsigned long long *count = _count; - struct test_array *local_ptr; + int *local_ptr; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), @@ -240,7 +203,7 @@ void *thr_reader(void *_count) local_ptr = rcu_dereference(test_rcu_pointer); rcu_debug_yield_read(); if (local_ptr) - assert(local_ptr->a == 8); + assert(*local_ptr == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); @@ -269,7 +232,7 @@ void *thr_reader(void *_count) void *thr_writer(void *_count) { unsigned long long *count = _count; - struct test_array *new, *old; + int *new, *old; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), @@ -283,18 +246,16 @@ void *thr_writer(void *_count) cmm_smp_mb(); for (;;) { - rcu_copy_mutex_lock(); - new = test_array_alloc(); - new->a = 8; + new = malloc(sizeof(int)); + assert(new); + *new = 8; old = rcu_xchg_pointer(&test_rcu_pointer, new); if (caa_unlikely(wduration)) loop_sleep(wduration); synchronize_rcu(); - /* can be done after unlock */ if (old) - old->a = 0; - test_array_free(old); - rcu_copy_mutex_unlock(); + *old = 0; + free(old); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; @@ -412,7 +373,6 @@ int main(int argc, char **argv) "main", (unsigned long) pthread_self(), (unsigned long) gettid()); - test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); @@ -462,8 +422,7 @@ int main(int argc, char **argv) argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); - test_array_free(test_rcu_pointer); - free(test_array); + free(test_rcu_pointer); free(tid_reader); free(tid_writer); free(count_reader); -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sat Nov 17 11:16:47 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sat, 17 Nov 2012 11:16:47 -0500 Subject: [lttng-dev] [PATCH 8/8] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353169007-31389-9-git-send-email-mathieu.desnoyers@efficios.com> CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 5b341b5..7f747ed 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -36,6 +36,7 @@ #include #include "urcu/wfcqueue.h" +#include "urcu/wfstack.h" #include "urcu/map/urcu-qsbr.h" #define BUILD_QSBR_LIB #include "urcu/static/urcu-qsbr.h" @@ -78,6 +79,35 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); static CDS_LIST_HEAD(registry); +/* + * Number of busy-loop attempts before waiting on futex for grace period + * batching. + */ +#define RCU_AWAKE_ATTEMPTS 1000 + +enum adapt_wakeup_state { + /* AWAKE_WAITING is compared directly (futex compares it). */ + AWAKE_WAITING = 0, + /* non-zero are used as masks. */ + AWAKE_WAKEUP = (1 << 0), + AWAKE_AWAKENED = (1 << 1), + AWAKE_TEARDOWN = (1 << 2), +}; + +struct gp_waiters_thread { + struct cds_wfs_node node; + int32_t wait_futex; +}; + +/* + * Stack keeping threads awaiting to wait for a grace period. Contains + * struct gp_waiters_thread objects. + */ +static struct cds_wfs_stack gp_waiters = { + .head = CDS_WFS_END, + .lock = PTHREAD_MUTEX_INITIALIZER, +}; + static void mutex_lock(pthread_mutex_t *mutex) { int ret; @@ -116,6 +146,58 @@ static void wait_gp(void) NULL, NULL, 0); } +/* + * Note: urcu_adaptative_wake_up needs "value" to stay allocated + * throughout its execution. In this scheme, the waiter owns the futex + * memory, and we only allow it to free this memory when it receives the + * AWAKE_TEARDOWN flag. + */ +static void urcu_adaptative_wake_up(int32_t *value) +{ + cmm_smp_mb(); + assert(uatomic_read(value) == AWAKE_WAITING); + uatomic_set(value, AWAKE_WAKEUP); + if (!(uatomic_read(value) & AWAKE_AWAKENED)) + futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); + /* Allow teardown of "value" memory. */ + uatomic_or(value, AWAKE_TEARDOWN); +} + +/* + * Caller must initialize "value" to AWAKE_WAITING before passing its + * memory to waker thread. + */ +static void urcu_adaptative_busy_wait(int32_t *value) +{ + unsigned int i; + + /* Load and test condition before read futex */ + cmm_smp_rmb(); + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { + if (uatomic_read(value) != AWAKE_WAITING) + goto skip_futex_wait; + caa_cpu_relax(); + } + futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); +skip_futex_wait: + + /* Tell waker thread than we are awakened. */ + uatomic_or(value, AWAKE_AWAKENED); + + /* + * Wait until waker thread lets us know it's ok to tear down + * memory allocated for value. + */ + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { + if (uatomic_read(value) & AWAKE_TEARDOWN) + break; + caa_cpu_relax(); + } + while (!(uatomic_read(value) & AWAKE_TEARDOWN)) + poll(NULL, 0, 10); + assert(uatomic_read(value) & AWAKE_TEARDOWN); +} + static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, struct cds_list_head *qsreaders) @@ -198,6 +280,9 @@ void synchronize_rcu(void) CDS_LIST_HEAD(cur_snap_readers); CDS_LIST_HEAD(qsreaders); unsigned long was_online; + struct gp_waiters_thread gp_waiters_thread; + struct cds_wfs_head *gp_waiters_head; + struct cds_wfs_node *waiters_iter, *waiters_iter_n; was_online = URCU_TLS(rcu_reader).ctr; @@ -214,8 +299,26 @@ void synchronize_rcu(void) else cmm_smp_mb(); + /* + * Add ourself to gp_waiters stack of threads awaiting to wait + * for a grace period. Proceed to perform the grace period only + * if we are the first thread added into the stack. + */ + cds_wfs_node_init(&gp_waiters_thread.node); + gp_waiters_thread.wait_futex = AWAKE_WAITING; + if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { + /* Not first in stack: will be awakened by another thread. */ + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); + goto gp_end; + } + mutex_lock(&rcu_gp_lock); + /* + * Pop all waiters into our local stack head. + */ + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); + if (cds_list_empty(®istry)) goto out; @@ -272,6 +375,19 @@ void synchronize_rcu(void) out: mutex_unlock(&rcu_gp_lock); + /* Wake all waiters in our stack head, excluding ourself. */ + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, + waiters_iter_n) { + struct gp_waiters_thread *wt; + + wt = caa_container_of(waiters_iter, + struct gp_waiters_thread, node); + if (wt == &gp_waiters_thread) + continue; + urcu_adaptative_wake_up(&wt->wait_futex); + } + +gp_end: /* * Finish waiting for reader threads before letting the old ptr being * freed. @@ -286,6 +402,9 @@ void synchronize_rcu(void) { CDS_LIST_HEAD(qsreaders); unsigned long was_online; + struct gp_waiters_thread gp_waiters_thread; + struct cds_wfs_head *gp_waiters_head; + struct cds_wfs_node *waiters_iter, *waiters_iter_n; was_online = URCU_TLS(rcu_reader).ctr; @@ -299,7 +418,26 @@ void synchronize_rcu(void) else cmm_smp_mb(); + /* + * Add ourself to gp_waiters stack of threads awaiting to wait + * for a grace period. Proceed to perform the grace period only + * if we are the first thread added into the stack. + */ + cds_wfs_node_init(&gp_waiters_thread.node); + gp_waiters_thread.wait_futex = AWAKE_WAITING; + if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { + /* Not first in stack: will be awakened by another thread. */ + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); + goto gp_end; + } + mutex_lock(&rcu_gp_lock); + + /* + * Pop all waiters into our local stack head. + */ + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); + if (cds_list_empty(®istry)) goto out; @@ -334,6 +472,19 @@ void synchronize_rcu(void) out: mutex_unlock(&rcu_gp_lock); + /* Wake all waiters in our stack head, excluding ourself. */ + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, + waiters_iter_n) { + struct gp_waiters_thread *wt; + + wt = caa_container_of(waiters_iter, + struct gp_waiters_thread, node); + if (wt == &gp_waiters_thread) + continue; + urcu_adaptative_wake_up(&wt->wait_futex); + } + +gp_end: if (was_online) rcu_thread_online(); else -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sun Nov 18 10:40:41 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 18 Nov 2012 10:40:41 -0500 Subject: [lttng-dev] [PATCH] wfcqueue: enqueue and splice return queue state Message-ID: <20121118154041.GA29968@Krystal> enqueue can return whether the queue was empty or not prior to enqueue. splice can return this information about destination queue too, but there are more cases to handle, because we don't touch the destination queue if the source queue was empty, and in the nonblocking case, we return that we would need to block on the source queue. The destination queue state is sampled atomically with enqueue/splice to destination operations. Knowing this state is useful when "ownership" on a batch of queue items can be assigned to those enqueuing the first items, e.g. to implement wait/wakeup schemes. Signed-off-by: Mathieu Desnoyers CC: Paul E. McKenney CC: Lai Jiangshan --- diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 8733771..b386950 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -128,7 +128,7 @@ static inline void _cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, assert(!ret); } -static inline void ___cds_wfcq_append(struct cds_wfcq_head *head, +static inline bool ___cds_wfcq_append(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *new_head, struct cds_wfcq_node *new_tail) @@ -152,6 +152,11 @@ static inline void ___cds_wfcq_append(struct cds_wfcq_head *head, * perspective. */ CMM_STORE_SHARED(old_tail->next, new_head); + /* + * Return false if queue was empty prior to adding the node, + * else return true. + */ + return old_tail != &head->node; } /* @@ -159,12 +164,15 @@ static inline void ___cds_wfcq_append(struct cds_wfcq_head *head, * * Issues a full memory barrier before enqueue. No mutual exclusion is * required. + * + * Returns false if the queue was empty prior to adding the node. + * Returns true otherwise. */ -static inline void _cds_wfcq_enqueue(struct cds_wfcq_head *head, +static inline bool _cds_wfcq_enqueue(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *new_tail) { - ___cds_wfcq_append(head, tail, new_tail, new_tail); + return ___cds_wfcq_append(head, tail, new_tail, new_tail); } /* @@ -373,7 +381,7 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, return ___cds_wfcq_dequeue(head, tail, 0); } -static inline int +static inline enum cds_wfcq_ret ___cds_wfcq_splice( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, @@ -384,11 +392,11 @@ ___cds_wfcq_splice( struct cds_wfcq_node *head, *tail; if (_cds_wfcq_empty(src_q_head, src_q_tail)) - return 0; + return CDS_WFCQ_RET_SRC_EMPTY; head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); if (head == CDS_WFCQ_WOULDBLOCK) - return -1; + return CDS_WFCQ_RET_WOULDBLOCK; _cds_wfcq_node_init(&src_q_head->node); /* @@ -403,8 +411,10 @@ ___cds_wfcq_splice( * Append the spliced content of src_q into dest_q. Does not * require mutual exclusion on dest_q (wait-free). */ - ___cds_wfcq_append(dest_q_head, dest_q_tail, head, tail); - return 0; + if (___cds_wfcq_append(dest_q_head, dest_q_tail, head, tail)) + return CDS_WFCQ_RET_DEST_NON_EMPTY; + else + return CDS_WFCQ_RET_DEST_EMPTY; } @@ -415,25 +425,27 @@ ___cds_wfcq_splice( * dest_q must be already initialized. * Dequeue/splice/iteration mutual exclusion for src_q should be ensured * by the caller. + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. */ -static inline void +static inline enum cds_wfcq_ret ___cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { - (void) ___cds_wfcq_splice(dest_q_head, dest_q_tail, + return ___cds_wfcq_splice(dest_q_head, dest_q_tail, src_q_head, src_q_tail, 1); } /* * __cds_wfcq_splice_nonblocking: enqueue all src_q nodes at the end of dest_q. * - * Same as __cds_wfcq_splice_blocking, but returns nonzero if it needs to - * block. + * Same as __cds_wfcq_splice_blocking, but returns + * CDS_WFCQ_RET_WOULDBLOCK if it needs to block. */ -static inline int +static inline enum cds_wfcq_ret ___cds_wfcq_splice_nonblocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, @@ -474,18 +486,23 @@ _cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, * consistent, but no other memory ordering is ensured. * Mutual exlusion with cds_wfcq_dequeue_blocking and dequeue lock is * ensured. + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. */ -static inline void +static inline enum cds_wfcq_ret _cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { + enum cds_wfcq_ret ret; + _cds_wfcq_dequeue_lock(src_q_head, src_q_tail); - ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, + ret = ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, src_q_head, src_q_tail); _cds_wfcq_dequeue_unlock(src_q_head, src_q_tail); + return ret; } #ifdef __cplusplus diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h index fe2862e..ddf6b87 100644 --- a/urcu/wfcqueue.h +++ b/urcu/wfcqueue.h @@ -45,6 +45,13 @@ extern "C" { #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) +enum cds_wfcq_ret { + CDS_WFCQ_RET_WOULDBLOCK = -1, + CDS_WFCQ_RET_DEST_EMPTY = 0, + CDS_WFCQ_RET_DEST_NON_EMPTY = 1, + CDS_WFCQ_RET_SRC_EMPTY = 2, +}; + struct cds_wfcq_node { struct cds_wfcq_node *next; }; @@ -156,8 +163,11 @@ extern void cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, * * Issues a full memory barrier before enqueue. No mutual exclusion is * required. + * + * Returns false if the queue was empty prior to adding the node. + * Returns true otherwise. */ -extern void cds_wfcq_enqueue(struct cds_wfcq_head *head, +extern bool cds_wfcq_enqueue(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *node); @@ -183,8 +193,11 @@ extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( * consistent, but no other memory ordering is ensured. * Mutual exlusion with cds_wfcq_dequeue_blocking and dequeue lock is * ensured. + * + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Cannot block. */ -extern void cds_wfcq_splice_blocking( +extern enum cds_wfcq_ret cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, @@ -222,8 +235,11 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( * consistent, but no other memory ordering is ensured. * Dequeue/splice/iteration mutual exclusion for src_q should be ensured * by the caller. + * + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Cannot block. */ -extern void __cds_wfcq_splice_blocking( +extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, @@ -232,10 +248,10 @@ extern void __cds_wfcq_splice_blocking( /* * __cds_wfcq_splice_nonblocking: enqueue all src_q nodes at the end of dest_q. * - * Same as __cds_wfcq_splice_blocking, but returns nonzero if it needs to - * block. + * Same as __cds_wfcq_splice_blocking, but returns + * CDS_WFCQ_RET_WOULDBLOCK if it needs to block. */ -extern int __cds_wfcq_splice_nonblocking( +extern enum cds_wfcq_ret __cds_wfcq_splice_nonblocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, diff --git a/wfcqueue.c b/wfcqueue.c index 90b810e..207df95 100644 --- a/wfcqueue.c +++ b/wfcqueue.c @@ -47,11 +47,11 @@ bool cds_wfcq_empty(struct cds_wfcq_head *head, return _cds_wfcq_empty(head, tail); } -void cds_wfcq_enqueue(struct cds_wfcq_head *head, +bool cds_wfcq_enqueue(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *node) { - _cds_wfcq_enqueue(head, tail, node); + return _cds_wfcq_enqueue(head, tail, node); } void cds_wfcq_dequeue_lock(struct cds_wfcq_head *head, @@ -73,13 +73,13 @@ struct cds_wfcq_node *cds_wfcq_dequeue_blocking( return _cds_wfcq_dequeue_blocking(head, tail); } -void cds_wfcq_splice_blocking( +enum cds_wfcq_ret cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { - _cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, + return _cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, src_q_head, src_q_tail); } @@ -97,17 +97,17 @@ struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( return ___cds_wfcq_dequeue_nonblocking(head, tail); } -void __cds_wfcq_splice_blocking( +enum cds_wfcq_ret __cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { - ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, + return ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, src_q_head, src_q_tail); } -int __cds_wfcq_splice_nonblocking( +enum cds_wfcq_ret __cds_wfcq_splice_nonblocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Nov 18 10:43:14 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 18 Nov 2012 10:43:14 -0500 Subject: [lttng-dev] [PATCH] test wfcqueue: add tests for queue state return value Message-ID: <20121118154314.GB29968@Krystal> with e.g. ./test_urcu_wfcq 2 2 10 -w we can confirm that we see as many "enqueue to empty queue" as we see "splice from non-empty queue", which confirms that the queue state returned by enqueue is indeed sampled atomically with enqueue. Signed-off-by: Mathieu Desnoyers CC: Paul E. McKenney CC: Lai Jiangshan --- diff --git a/tests/test_urcu_wfcq.c b/tests/test_urcu_wfcq.c index f90fc14..1dc7e0d 100644 --- a/tests/test_urcu_wfcq.c +++ b/tests/test_urcu_wfcq.c @@ -75,7 +75,7 @@ enum test_sync { static enum test_sync test_sync; -static volatile int test_go, test_stop; +static volatile int test_go, test_stop_enqueue, test_stop_dequeue; static unsigned long rduration; @@ -92,7 +92,7 @@ static inline void loop_sleep(unsigned long loops) static int verbose_mode; -static int test_dequeue, test_splice; +static int test_dequeue, test_splice, test_wait_empty; #define printf_verbose(fmt, args...) \ do { \ @@ -150,12 +150,12 @@ static void set_affinity(void) */ static int test_duration_dequeue(void) { - return !test_stop; + return !test_stop_dequeue; } static int test_duration_enqueue(void) { - return !test_stop; + return !test_stop_enqueue; } static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); @@ -163,6 +163,8 @@ static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); +static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); +static DEFINE_URCU_TLS(unsigned long long, nr_splice); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -173,6 +175,7 @@ static struct cds_wfcq_tail __attribute__((aligned(CAA_CACHE_LINE_SIZE))) tail; static void *thr_enqueuer(void *_count) { unsigned long long *count = _count; + bool was_nonempty; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "enqueuer", (unsigned long) pthread_self(), @@ -190,8 +193,10 @@ static void *thr_enqueuer(void *_count) if (!node) goto fail; cds_wfcq_node_init(node); - cds_wfcq_enqueue(&head, &tail, node); + was_nonempty = cds_wfcq_enqueue(&head, &tail, node); URCU_TLS(nr_successful_enqueues)++; + if (!was_nonempty) + URCU_TLS(nr_empty_dest_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); @@ -203,11 +208,15 @@ fail: count[0] = URCU_TLS(nr_enqueues); count[1] = URCU_TLS(nr_successful_enqueues); + count[2] = URCU_TLS(nr_empty_dest_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " - "enqueues %llu successful_enqueues %llu\n", + "enqueues %llu successful_enqueues %llu, " + "empty_dest_enqueues %llu\n", pthread_self(), (unsigned long) gettid(), - URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); + URCU_TLS(nr_enqueues), + URCU_TLS(nr_successful_enqueues), + URCU_TLS(nr_empty_dest_enqueues)); return ((void*)1); } @@ -233,16 +242,33 @@ static void do_test_splice(enum test_sync sync) struct cds_wfcq_head tmp_head; struct cds_wfcq_tail tmp_tail; struct cds_wfcq_node *node, *n; + enum cds_wfcq_ret ret; cds_wfcq_init(&tmp_head, &tmp_tail); if (sync == TEST_SYNC_MUTEX) - cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, + ret = cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, &head, &tail); else - __cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, + ret = __cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, &head, &tail); + switch (ret) { + case CDS_WFCQ_RET_WOULDBLOCK: + assert(0); /* blocking call */ + break; + case CDS_WFCQ_RET_DEST_EMPTY: + URCU_TLS(nr_splice)++; + /* ok */ + break; + case CDS_WFCQ_RET_DEST_NON_EMPTY: + assert(0); /* entirely unexpected */ + break; + case CDS_WFCQ_RET_SRC_EMPTY: + /* ok, we could even skip iteration on dest if we wanted */ + break; + } + __cds_wfcq_for_each_blocking_safe(&tmp_head, &tmp_tail, node, n) { free(node); URCU_TLS(nr_successful_dequeues)++; @@ -286,12 +312,15 @@ static void *thr_dequeuer(void *_count) } printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " - "dequeues %llu, successful_dequeues %llu\n", + "dequeues %llu, successful_dequeues %llu, " + "nr_splice %llu\n", pthread_self(), (unsigned long) gettid(), - URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues), + URCU_TLS(nr_splice)); count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); + count[2] = URCU_TLS(nr_splice); return ((void*)2); } @@ -320,6 +349,7 @@ static void show_usage(int argc, char **argv) printf(" [-M] (use mutex external synchronization)"); printf(" [-0] (use no external synchronization)"); printf(" Note: default: mutex external synchronization used."); + printf(" [-w] Wait for dequeuer to empty queue"); printf("\n"); } @@ -331,9 +361,11 @@ int main(int argc, char **argv) unsigned long long *count_enqueuer, *count_dequeuer; unsigned long long tot_enqueues = 0, tot_dequeues = 0; unsigned long long tot_successful_enqueues = 0, - tot_successful_dequeues = 0; + tot_successful_dequeues = 0, + tot_empty_dest_enqueues = 0, + tot_splice = 0; unsigned long long end_dequeues = 0; - int i, a; + int i, a, retval = 0; if (argc < 4) { show_usage(argc, argv); @@ -401,6 +433,9 @@ int main(int argc, char **argv) case '0': test_sync = TEST_SYNC_NONE; break; + case 'w': + test_wait_empty = 1; + break; } } @@ -419,6 +454,8 @@ int main(int argc, char **argv) printf_verbose("External sync: mutex.\n"); else printf_verbose("External sync: none.\n"); + if (test_wait_empty) + printf_verbose("Wait for dequeuers to empty queue.\n"); printf_verbose("Writer delay : %lu loops.\n", rduration); printf_verbose("Reader duration : %lu loops.\n", wdelay); printf_verbose("thread %-6s, thread id : %lx, tid %lu\n", @@ -427,21 +464,21 @@ int main(int argc, char **argv) tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); - count_enqueuer = malloc(2 * sizeof(*count_enqueuer) * nr_enqueuers); - count_dequeuer = malloc(2 * sizeof(*count_dequeuer) * nr_dequeuers); + count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); + count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); cds_wfcq_init(&head, &tail); next_aff = 0; for (i = 0; i < nr_enqueuers; i++) { err = pthread_create(&tid_enqueuer[i], NULL, thr_enqueuer, - &count_enqueuer[2 * i]); + &count_enqueuer[3 * i]); if (err != 0) exit(1); } for (i = 0; i < nr_dequeuers; i++) { err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, - &count_dequeuer[2 * i]); + &count_dequeuer[3 * i]); if (err != 0) exit(1); } @@ -456,21 +493,31 @@ int main(int argc, char **argv) write (1, ".", 1); } - test_stop = 1; + test_stop_enqueue = 1; + + if (test_wait_empty) { + while (!cds_wfcq_empty(&head, &tail)) { + sleep(1); + } + } + + test_stop_dequeue = 1; for (i = 0; i < nr_enqueuers; i++) { err = pthread_join(tid_enqueuer[i], &tret); if (err != 0) exit(1); - tot_enqueues += count_enqueuer[2 * i]; - tot_successful_enqueues += count_enqueuer[2 * i + 1]; + tot_enqueues += count_enqueuer[3 * i]; + tot_successful_enqueues += count_enqueuer[3 * i + 1]; + tot_empty_dest_enqueues += count_enqueuer[3 * i + 2]; } for (i = 0; i < nr_dequeuers; i++) { err = pthread_join(tid_dequeuer[i], &tret); if (err != 0) exit(1); - tot_dequeues += count_dequeuer[2 * i]; - tot_successful_dequeues += count_dequeuer[2 * i + 1]; + tot_dequeues += count_dequeuer[3 * i]; + tot_successful_dequeues += count_dequeuer[3 * i + 1]; + tot_splice += count_dequeuer[3 * i + 2]; } test_end(&end_dequeues); @@ -478,27 +525,50 @@ int main(int argc, char **argv) printf_verbose("total number of enqueues : %llu, dequeues %llu\n", tot_enqueues, tot_dequeues); printf_verbose("total number of successful enqueues : %llu, " - "successful dequeues %llu\n", - tot_successful_enqueues, tot_successful_dequeues); + "enqueues to empty dest : %llu, " + "successful dequeues %llu, ", + "splice : %llu\n", + tot_successful_enqueues, + tot_empty_dest_enqueues, + tot_successful_dequeues, + tot_splice); printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " "nr_dequeuers %3u " "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " - "successful enqueues %12llu successful dequeues %12llu " + "successful enqueues %12llu enqueues to empty dest %12llu " + "successful dequeues %12llu splice %12llu " "end_dequeues %llu nr_ops %12llu\n", argv[0], duration, nr_enqueuers, wdelay, nr_dequeuers, rduration, tot_enqueues, tot_dequeues, tot_successful_enqueues, - tot_successful_dequeues, end_dequeues, + tot_empty_dest_enqueues, + tot_successful_dequeues, tot_splice, end_dequeues, tot_enqueues + tot_dequeues); - if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) + + if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " "succ. dequeues + end dequeues %llu.\n", tot_successful_enqueues, tot_successful_dequeues + end_dequeues); + retval = 1; + } + /* + * If only using splice to dequeue, the enqueuer should see + * exactly as many empty queues than the number of non-empty + * src splice. + */ + if (test_wait_empty && (test_splice && !test_dequeue) + && tot_empty_dest_enqueues != tot_splice) { + printf("WARNING! Discrepancy between empty enqueue (%llu) and " + "number of non-empty splice (%llu)\n", + tot_empty_dest_enqueues, + tot_splice); + retval = 1; + } free(count_enqueuer); free(count_dequeuer); free(tid_enqueuer); free(tid_dequeuer); - return 0; + return retval; } -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From David.OShea at quantum.com Sun Nov 18 23:06:19 2012 From: David.OShea at quantum.com (David OShea) Date: Mon, 19 Nov 2012 04:06:19 +0000 Subject: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust-tracepoint-event.h needs -Wsystem-headers Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> Hi all, I noticed that ust-tracepoint-event.h includes: """ /* * Stage 0 of tracepoint event generation. * * Check that each TRACEPOINT_EVENT provider argument match the * TRACEPOINT_PROVIDER by creating dummy callbacks. */ """ If I ask GCC to output the preprocessor's output, I can see that the checks are behaving as expected - creating calls to functions whose names include the TRACEPOINT_EVENTs' provider arguments, and defining a function whose name includes the TRACEPOINT_PROVIDER value. However, because I have installed the LTTng header files - they are in /usr/include/lttng - GCC (I'm using version 4.3.3) does not actually output any warnings regarding the calls to undefined functions because they are made in a "system header file". If I pass -Wsystem-headers to GCC, then it does output warnings when I have a TRACEPOINT_PROVIDER mismatch, but I also get lots of warnings about unused parameters due to the way the tracepoint definitions work. >From some experimentation, it looks like enabling -Wsystem-headers, even if only for the trace provider .c file, would probably result in us getting lots of spurious warnings due to various Linux system header files too, so we don't really want to enable that. I'm not sure if there is any way you could "fix" this so that -Wsystem-headers isn't required, but perhaps it would at least be worth documenting that this flag could be used - but perhaps not recommend it - to enable those checks to occur. This was seen with lttng-ust-2.0.5 patched with commit 009745db "Cache the procname per-thread rather than per-process to take into account that prctl() can be used to set thread names." and commit e699eda "don't spawn per-user thread if HOME is not set". Thanks, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From laijs at cn.fujitsu.com Mon Nov 19 02:16:34 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Mon, 19 Nov 2012 15:16:34 +0800 Subject: [lttng-dev] [PATCH 5/8] urcu-mb/signal/membarrier: move quiescent threads to separate list In-Reply-To: <1353169007-31389-6-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> <1353169007-31389-6-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <50A9DCD2.7000009@cn.fujitsu.com> On 11/18/2012 12:16 AM, Mathieu Desnoyers wrote: > Accelerate 2-phase grace period by not having to iterate twice on > threads not nested within a RCU read-side lock. You almost gain nothing. The first wait_for_readers() waits none very likely. > @@ -341,7 +361,12 @@ void synchronize_rcu(void) > /* > * Wait for readers to observe new parity or be quiescent. > */ > - wait_for_readers(); > + wait_for_readers(®istry, NULL, &qsreaders); wait_for_readers(&cur_snap_readers, NULL, &qsreaders); From laijs at cn.fujitsu.com Mon Nov 19 02:52:18 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Mon, 19 Nov 2012 15:52:18 +0800 Subject: [lttng-dev] userspace rcu flavor improvements In-Reply-To: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <50A9E532.6000706@cn.fujitsu.com> On 11/18/2012 12:16 AM, Mathieu Desnoyers wrote: > Here are a couple of improvements for all userspace RCU flavors. Many > thanks to Alan Stern for his suggestions. It makes urcu like SRCU. (sync_rcu = check zero + flip + check zero) If I have time, I may port more SRCU code to urcu. > > Patch 8/8 is only done for qsbr so far, and proposed as RFC. I'd like to > try and benchmark other approaches to concurrent grace periods too. > > Feedback is welcome, > > Thanks, > > Mathieu > > From wangwangwar at gmail.com Mon Nov 19 06:18:11 2012 From: wangwangwar at gmail.com (wang wangwar) Date: Mon, 19 Nov 2012 19:18:11 +0800 Subject: [lttng-dev] lttng - ubuntu 11.10 - problem Message-ID: This is my simple solution. Enter the lttng module build dir (like /var/lib/dkms/lttng-modules/2.0.0/build/ as your log says), open lttng-syscalls.c, comment the definition of is_compat_task(void) (line 32 to 35), finally > # make # make modules_install # depmod -a I don't know why but it just work:) My system is LinuxMint 12 (with Ubuntu 11.10 core), so I think it works to you, too. wang -------------- next part -------------- An HTML attachment was scrubbed... URL: From Andrew.McDermott at windriver.com Mon Nov 19 08:54:27 2012 From: Andrew.McDermott at windriver.com (McDermott, Andrew) Date: Mon, 19 Nov 2012 13:54:27 +0000 Subject: [lttng-dev] latest version of LTTng UST on Ubuntu 12.04 Message-ID: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> How often are the LTTng UST packages for Ubuntu updated? Having done a fresh install I see the version reported as: $ lttng version lttng version 2.0.1 - Annedd'ale but looking at the git repo I see there is v2.0.4 tag. Are these updates only available if built from source? In general I was trying to avoid the daily development versions from: https://launchpad.net/~lttng/+archive/daily. -- andy From mathieu.desnoyers at efficios.com Mon Nov 19 10:16:53 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 19 Nov 2012 10:16:53 -0500 Subject: [lttng-dev] [PATCH 5/8] urcu-mb/signal/membarrier: move quiescent threads to separate list In-Reply-To: <50A9DCD2.7000009@cn.fujitsu.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> <1353169007-31389-6-git-send-email-mathieu.desnoyers@efficios.com> <50A9DCD2.7000009@cn.fujitsu.com> Message-ID: <20121119151653.GA16248@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > On 11/18/2012 12:16 AM, Mathieu Desnoyers wrote: > > Accelerate 2-phase grace period by not having to iterate twice on > > threads not nested within a RCU read-side lock. > > You almost gain nothing. > The first wait_for_readers() waits none very likely. I agree with you that the speedup will probably be small, but as we start having more and more readers, most of which are outside of RCU read-side critical sections, iterating only once, rather than twice, on the list of readers seems to be a saving worth doing. Actually, when I implemented grace periods based on list move/splicing, it was my original intent to only touch threads as many times as we needed to observe them become quiescent. The "move quiescent threads to separate list" patches are completing that modification. > > > @@ -341,7 +361,12 @@ void synchronize_rcu(void) > > /* > > * Wait for readers to observe new parity or be quiescent. > > */ > > - wait_for_readers(); > > + wait_for_readers(®istry, NULL, &qsreaders); > > wait_for_readers(&cur_snap_readers, NULL, &qsreaders); Good catch, fixed in my dev branch. Thanks! Mathieu -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 19 10:17:52 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 19 Nov 2012 10:17:52 -0500 Subject: [lttng-dev] latest version of LTTng UST on Ubuntu 12.04 In-Reply-To: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> References: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> Message-ID: <20121119151752.GB16248@Krystal> Let's ask St?phane Graber, our Ubuntu packager. Thanks, Mathieu * McDermott, Andrew (Andrew.McDermott at windriver.com) wrote: > > How often are the LTTng UST packages for Ubuntu updated? > > Having done a fresh install I see the version reported as: > > $ lttng version > lttng version 2.0.1 - Annedd'ale > > but looking at the git repo I see there is v2.0.4 tag. Are these > updates only available if built from source? In general I was trying to > avoid the daily development versions from: > > https://launchpad.net/~lttng/+archive/daily. > > -- > andy > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 19 10:18:55 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 19 Nov 2012 10:18:55 -0500 Subject: [lttng-dev] userspace rcu flavor improvements In-Reply-To: <50A9E532.6000706@cn.fujitsu.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> <50A9E532.6000706@cn.fujitsu.com> Message-ID: <20121119151855.GC16248@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > On 11/18/2012 12:16 AM, Mathieu Desnoyers wrote: > > Here are a couple of improvements for all userspace RCU flavors. Many > > thanks to Alan Stern for his suggestions. > > > It makes urcu like SRCU. (sync_rcu = check zero + flip + check zero) Good to know :) > If I have time, I may port more SRCU code to urcu. That will certainly be interesting. Thanks! Mathieu > > > > > Patch 8/8 is only done for qsbr so far, and proposed as RFC. I'd like to > > try and benchmark other approaches to concurrent grace periods too. > > > > Feedback is welcome, > > > > Thanks, > > > > Mathieu > > > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From jbernard at debian.org Mon Nov 19 10:47:02 2012 From: jbernard at debian.org (Jon Bernard) Date: Mon, 19 Nov 2012 10:47:02 -0500 Subject: [lttng-dev] latest version of LTTng UST on Ubuntu 12.04 In-Reply-To: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> References: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> Message-ID: <20121119154702.GA4533@quintessa> * McDermott, Andrew wrote: > > How often are the LTTng UST packages for Ubuntu updated? > > Having done a fresh install I see the version reported as: > > $ lttng version > lttng version 2.0.1 - Annedd'ale > > but looking at the git repo I see there is v2.0.4 tag. Are these > updates only available if built from source? In general I was trying to > avoid the daily development versions from: > > https://launchpad.net/~lttng/+archive/daily. The version is unlikely to change unless a security flaw or other major bug is discovered. The PPA builds are prepared by the same folks that prepared the packages for 12.04, so their quality will be consistent (high). If you need the latest code, I think that is a good place to start. -- Jon From paulmck at linux.vnet.ibm.com Mon Nov 19 11:23:07 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Mon, 19 Nov 2012 08:23:07 -0800 Subject: [lttng-dev] userspace rcu flavor improvements In-Reply-To: <50A9E532.6000706@cn.fujitsu.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> <50A9E532.6000706@cn.fujitsu.com> Message-ID: <20121119162307.GE2829@linux.vnet.ibm.com> On Mon, Nov 19, 2012 at 03:52:18PM +0800, Lai Jiangshan wrote: > On 11/18/2012 12:16 AM, Mathieu Desnoyers wrote: > > Here are a couple of improvements for all userspace RCU flavors. Many > > thanks to Alan Stern for his suggestions. > > It makes urcu like SRCU. (sync_rcu = check zero + flip + check zero) > If I have time, I may port more SRCU code to urcu. I am sure that this is obvious to everyone, but I cannot help restating it. There is one important difference between user code and kernel code, though. In the kernel, we track by CPU, so one of SRCU's big jobs is to track multiple tasks using the same CPU. This opens the possibility of preemption, which is one of the things that complicates SRCU's design. In contrast, user-mode RCU tracks tasks without multiplexing. This allows simplifications that are similar to those that could be achieved in the kernel if we were willing to disable preemption across the entire SRCU read-side critical section. So although I am all for user-mode RCU taking advantage of any technology we have at hand, we do need to be careful to avoid needless complexity. > > Patch 8/8 is only done for qsbr so far, and proposed as RFC. I'd like to > > try and benchmark other approaches to concurrent grace periods too. The concurrent grace periods are the big win, in my opinion. ;-) Thanx, Paul > > Feedback is welcome, > > > > Thanks, > > > > Mathieu > > > > > From mathieu.desnoyers at efficios.com Mon Nov 19 11:26:18 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 19 Nov 2012 11:26:18 -0500 Subject: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust-tracepoint-event.h needs -Wsystem-headers In-Reply-To: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> Message-ID: <20121119162618.GA17428@Krystal> * David OShea (David.OShea at quantum.com) wrote: > Hi all, > > I noticed that ust-tracepoint-event.h includes: > > """ > /* > * Stage 0 of tracepoint event generation. > * > * Check that each TRACEPOINT_EVENT provider argument match the > * TRACEPOINT_PROVIDER by creating dummy callbacks. > */ > """ > > If I ask GCC to output the preprocessor's output, I can see that the > checks are behaving as expected - creating calls to functions whose > names include the TRACEPOINT_EVENTs' provider arguments, and defining > a function whose name includes the TRACEPOINT_PROVIDER value. > However, because I have installed the LTTng header files - they are in > /usr/include/lttng - GCC (I'm using version 4.3.3) does not actually > output any warnings regarding the calls to undefined functions because > they are made in a "system header file". If I pass -Wsystem-headers > to GCC, then it does output warnings when I have a TRACEPOINT_PROVIDER > mismatch, but I also get lots of warnings about unused parameters due > to the way the tracepoint definitions work. > > From some experimentation, it looks like enabling -Wsystem-headers, > even if only for the trace provider .c file, would probably result in > us getting lots of spurious warnings due to various Linux system > header files too, so we don't really want to enable that. We had to enable -Wsystem-headers in UST tests/hello and tests/demo Makefile.am. Indeed, it should be documented. And yes, we see some warnings in Linux system headers about missing prototypes. I think we should report these to distro and/or Linux kernel upstream. > I'm not sure if there is any way you could "fix" this so that > -Wsystem-headers isn't required, but perhaps it would at least be > worth documenting that this flag could be used - but perhaps not > recommend it - to enable those checks to occur. I have not found any way to show those warnings from UST system headers without -Wsystem-headers. We have the following scenario: probe C file -> includes ust probe description file -> includes tracepoint-event.h (system header) -> includes ust probe description file -> includes ust-tracepoint-event.h (system header) [1] For each stage: -> undef/define macros -> includes ust probe description file Since the actual functions are created by the compiler in the scope of ust-tracepoint-event.h [1] (a system header), the warnings are inhibited unless we specify -Wsystem-headers. When we build within the UST tree, since the build fetches the headers locally from the tree, we see those warnings even without -Wsystem-headers. So I guess documenting this would be the right way to do it, unless anyone has a better idea ? Thanks, Mathieu > This was seen with lttng-ust-2.0.5 patched with commit 009745db "Cache > the procname per-thread rather than per-process to take into account > that prctl() can be used to set thread names." and commit e699eda > "don't spawn per-user thread if HOME is not set". > > Thanks, > David > [...] -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 19 12:05:19 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 19 Nov 2012 12:05:19 -0500 Subject: [lttng-dev] userspace rcu flavor improvements In-Reply-To: <20121119162307.GE2829@linux.vnet.ibm.com> References: <1353169007-31389-1-git-send-email-mathieu.desnoyers@efficios.com> <50A9E532.6000706@cn.fujitsu.com> <20121119162307.GE2829@linux.vnet.ibm.com> Message-ID: <20121119170519.GB17428@Krystal> * Paul E. McKenney (paulmck at linux.vnet.ibm.com) wrote: > On Mon, Nov 19, 2012 at 03:52:18PM +0800, Lai Jiangshan wrote: > > On 11/18/2012 12:16 AM, Mathieu Desnoyers wrote: > > > Here are a couple of improvements for all userspace RCU flavors. Many > > > thanks to Alan Stern for his suggestions. > > > > It makes urcu like SRCU. (sync_rcu = check zero + flip + check zero) > > If I have time, I may port more SRCU code to urcu. > > I am sure that this is obvious to everyone, but I cannot help restating > it. There is one important difference between user code and kernel code, > though. In the kernel, we track by CPU, so one of SRCU's big jobs is > to track multiple tasks using the same CPU. This opens the possibility > of preemption, which is one of the things that complicates SRCU's design. > > In contrast, user-mode RCU tracks tasks without multiplexing. This > allows simplifications that are similar to those that could be achieved > in the kernel if we were willing to disable preemption across the entire > SRCU read-side critical section. > > So although I am all for user-mode RCU taking advantage of any technology > we have at hand, we do need to be careful to avoid needless complexity. Very good point! Indeed, when considering modifications to URCU, I will be considering all of those elements: - Added complexity (verification cost), + Speedup, + Lower latency, + Better scalability, + Lower power consumption, So yes, I'm all for improving URCU synchronisation, but I might be reluctant to pull modifications that increase complexity significantly without very significant benefits. > > > > Patch 8/8 is only done for qsbr so far, and proposed as RFC. I'd like to > > > try and benchmark other approaches to concurrent grace periods too. > > The concurrent grace periods are the big win, in my opinion. ;-) I've done some basic benchmarking on the approach taken by patch 8/8, and it leads to very interesting scalability improvement and speedups, e.g., on a 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater threads, each updater using synchronize_rcu()): * Serialized grace periods : ./test_urcu_qsbr 4 20 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 20251412728 nr_writes 1826331 nr_ops 20253239059 * Batched grace periods : ./test_urcu_qsbr 4 20 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 15141994746 nr_writes 9382515 nr_ops 15151377261 For a 9382515/1826331 = 5.13 speedup Of course, we can see that readers have slowed down, probably due to increased update traffic, given there is no change to the read-side code whatsoever. Now let's see the penality of managing the stack for single-updater. With 4 readers, single updater: * Serialized grace periods : ./test_urcu_qsbr 4 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 19240784755 nr_writes 2130839 nr_ops 19242915594 * Batched grace periods : ./test_urcu_qsbr 4 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 19160162768 nr_writes 2253068 nr_ops 1916241583 2253068 vs 2137036 -> a couple of runs show that this difference is lost in the noise for single updater. So given that implementing a real "concurrent" approach for grace periods would take a while and adds a lot of complexity, I am tempted to merge the batching approach given it does not add complexity to the synchronization algorithm, and already shows interesting speedup. Moreover, we can easily remove batching if it appears not to be needed in the future. Thoughts ? Thanks, Mathieu > > Thanx, Paul > > > > Feedback is welcome, > > > > > > Thanks, > > > > > > Mathieu > > > > > > > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From stgraber at ubuntu.com Mon Nov 19 12:51:19 2012 From: stgraber at ubuntu.com (=?ISO-8859-1?Q?St=E9phane_Graber?=) Date: Mon, 19 Nov 2012 12:51:19 -0500 Subject: [lttng-dev] latest version of LTTng UST on Ubuntu 12.04 In-Reply-To: <20121119151752.GB16248@Krystal> References: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> <20121119151752.GB16248@Krystal> Message-ID: <50AA7197.4080508@ubuntu.com> Hi, Sorry, I've been terribly busy lately. Ubuntu has a pretty strict policy of only accepting bugfixes in the -updates pocket post-release. For LTTng, the 2.0.x series is supposed to be feature stable so should in theory be fine to push to the -updates pocket. However for that to happen, someone needs to grab all the lttng releases from 2.0.1 and check and justify every changelog entry. My plan was to spend some time doing that once babeltrace 1.0 is released which I now see actually happened recently. We also need to keep in mind that we can't push something to 12.04 that's more recent than what we have in 12.10 as we need to keep a working upgrade path between 12.04 and 12.10. So looking at the latest releases, I think we'd want: - lttng-tools - 2.0.4 - lttng-modules - 2.0.5 - lttng-ust - 2.0.5 - liburcu - 0.7.5 - babeltrace - 1.0.0 That'd mean the following stable release updates for Ubuntu 12.10: - lttng-tools 2.0.3 => 2.0.4 - lttng-modules 2.0.4 => 2.0.5 - ust 2.0.4 => 2.0.5 (the package changed name between 12.04 and 12.10) - liburcu 0.7.3 => 0.7.5 - babeltrace 1.0.0~rc4 => 1.0.0 And then the following stable release updates for Ubuntu 12.04 LTS: - lttng-tools 2.0.1 => 2.0.4 - lttng-modules 2.0.2 => 2.0.5 - lttng-ust 2.0.2 => 2.0.5 - liburcu 0.6.7 => 0.7.5 - babeltrace 1.0.0~rc1 => 1.0.0 As everyone of those would be a version change, they'd all need to come along with a detailed test plan on all 5 supported architectures (amd64, i386, powerpc, armel, armhf) detailing how upstart (lttng) is ensuring that no regression has happened. The libraries will also need to be ABI compatible as rebuilding all reverse-dependencies isn't an option post-release. I'd expect that work, assuming lttng upstream's current test plans are accepted by the Ubuntu Technical Board to be of sufficient quality to guarantee a regression-free update, to take a good dozen of hours to prepare followed by reactive work for the month following to get those into the updates pocket. I don't think I'll realistically have the time to do that work anytime soon as lttng isn't a package officially supported by Canonical and so doesn't fall in my day job activities. An alternative would be to get lttng into the backports pocket of Ubuntu 12.04, the process for that is quite a bit easier as it doesn't required Technical Board approval or the strict testing process but will be less visible to the users as they'll have to explicitly pull it from the backports pocket (by using apt-get install lttng-tools=2.0.4 for example). Hope this clarifies the current situation a little. On 11/19/2012 10:17 AM, Mathieu Desnoyers wrote: > Let's ask St?phane Graber, our Ubuntu packager. > > Thanks, > > Mathieu > > * McDermott, Andrew (Andrew.McDermott at windriver.com) wrote: >> >> How often are the LTTng UST packages for Ubuntu updated? >> >> Having done a fresh install I see the version reported as: >> >> $ lttng version >> lttng version 2.0.1 - Annedd'ale >> >> but looking at the git repo I see there is v2.0.4 tag. Are these >> updates only available if built from source? In general I was trying to >> avoid the daily development versions from: >> >> https://launchpad.net/~lttng/+archive/daily. >> >> -- >> andy -- St?phane Graber Ubuntu developer http://www.ubuntu.com -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 899 bytes Desc: OpenPGP digital signature URL: From Andrew.McDermott at windriver.com Tue Nov 20 06:22:56 2012 From: Andrew.McDermott at windriver.com (McDermott, Andrew) Date: Tue, 20 Nov 2012 11:22:56 +0000 Subject: [lttng-dev] latest version of LTTng UST on Ubuntu 12.04 In-Reply-To: <50AA7197.4080508@ubuntu.com> (=?utf-8?Q?=22St=C3=A9phane?= Graber"'s message of "Mon, 19 Nov 2012 12:51:19 -0500") References: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> <20121119151752.GB16248@Krystal> <50AA7197.4080508@ubuntu.com> Message-ID: <7F632A9222059A42AF70FCB7965774AA2098823E@ALA-MBB.corp.ad.wrs.com> St?phane Graber writes: > Hi, > > Sorry, I've been terribly busy lately. > > Ubuntu has a pretty strict policy of only accepting bugfixes in the > -updates pocket post-release. > > For LTTng, the 2.0.x series is supposed to be feature stable so should > in theory be fine to push to the -updates pocket. However for that to > happen, someone needs to grab all the lttng releases from 2.0.1 and > check and justify every changelog entry. > > My plan was to spend some time doing that once babeltrace 1.0 is > released which I now see actually happened recently. > > We also need to keep in mind that we can't push something to 12.04 > that's more recent than what we have in 12.10 as we need to keep a > working upgrade path between 12.04 and 12.10. > > So looking at the latest releases, I think we'd want: > - lttng-tools - 2.0.4 > - lttng-modules - 2.0.5 > - lttng-ust - 2.0.5 > - liburcu - 0.7.5 > - babeltrace - 1.0.0 > > That'd mean the following stable release updates for Ubuntu 12.10: > - lttng-tools 2.0.3 => 2.0.4 > - lttng-modules 2.0.4 => 2.0.5 > - ust 2.0.4 => 2.0.5 (the package changed name between 12.04 and 12.10) > - liburcu 0.7.3 => 0.7.5 > - babeltrace 1.0.0~rc4 => 1.0.0 > > And then the following stable release updates for Ubuntu 12.04 LTS: > - lttng-tools 2.0.1 => 2.0.4 > - lttng-modules 2.0.2 => 2.0.5 > - lttng-ust 2.0.2 => 2.0.5 > - liburcu 0.6.7 => 0.7.5 > - babeltrace 1.0.0~rc1 => 1.0.0 > > As everyone of those would be a version change, they'd all need to come > along with a detailed test plan on all 5 supported architectures (amd64, > i386, powerpc, armel, armhf) detailing how upstart (lttng) is ensuring > that no regression has happened. > The libraries will also need to be ABI compatible as rebuilding all > reverse-dependencies isn't an option post-release. > > I'd expect that work, assuming lttng upstream's current test plans are > accepted by the Ubuntu Technical Board to be of sufficient quality to > guarantee a regression-free update, to take a good dozen of hours to > prepare followed by reactive work for the month following to get those > into the updates pocket. > > I don't think I'll realistically have the time to do that work anytime > soon as lttng isn't a package officially supported by Canonical and so > doesn't fall in my day job activities. > > An alternative would be to get lttng into the backports pocket of Ubuntu > 12.04, the process for that is quite a bit easier as it doesn't required > Technical Board approval or the strict testing process but will be less > visible to the users as they'll have to explicitly pull it from the > backports pocket (by using apt-get install lttng-tools=2.0.4 for example). > > Hope this clarifies the current situation a little. It certainly does. Many thanks for the detailed reply. I think for now I will build from source - and pretty much those versions you have already highlighted. > > On 11/19/2012 10:17 AM, Mathieu Desnoyers wrote: >> Let's ask St?phane Graber, our Ubuntu packager. >> >> Thanks, >> >> Mathieu >> >> * McDermott, Andrew (Andrew.McDermott at windriver.com) wrote: >>> >>> How often are the LTTng UST packages for Ubuntu updated? >>> >>> Having done a fresh install I see the version reported as: >>> >>> $ lttng version >>> lttng version 2.0.1 - Annedd'ale >>> >>> but looking at the git repo I see there is v2.0.4 tag. Are these >>> updates only available if built from source? In general I was trying to >>> avoid the daily development versions from: >>> >>> https://launchpad.net/~lttng/+archive/daily. >>> >>> -- >>> andy From Andrew.McDermott at windriver.com Tue Nov 20 06:36:30 2012 From: Andrew.McDermott at windriver.com (McDermott, Andrew) Date: Tue, 20 Nov 2012 11:36:30 +0000 Subject: [lttng-dev] latest version of LTTng UST on Ubuntu 12.04 In-Reply-To: <20121119151752.GB16248@Krystal> (Mathieu Desnoyers's message of "Mon, 19 Nov 2012 10:17:52 -0500") References: <7F632A9222059A42AF70FCB7965774AA20987947@ALA-MBB.corp.ad.wrs.com> <20121119151752.GB16248@Krystal> Message-ID: <7F632A9222059A42AF70FCB7965774AA2098824E@ALA-MBB.corp.ad.wrs.com> Hi, > Let's ask St?phane Graber, our Ubuntu packager. The reason I was asking is because I get different behaviour between Fedora 16 and Ubuntu 12.04. I have a simple program that uses a few tracepoints to log "hello world" and a few scalar values. I run that as: lttng create -o /tmp/ust-demo.$$ lttng enable-event -u -a lttng start sudo LTTNG_UST_DEBUG=1 ./ust-tracedemo lttng stop sleep 1.50 lttng destroy babeltrace /tmp/ust-demo.$$ and on Ubuntu I see babletrace list my events on completion. On Fedora 16, building from source[1], I don't get any events recorded unless I add the 'tracing' group and ensure that there is a lttng-sessiond running as root. This is not true on Ubuntu. Note: the 'sudo' is deliberate but its presence (or absence) makes no difference on Fedora. On Fedora I see no trace created at all. Adding a pause to my program and running `lttng list -u' in another shell lists no active tracepoints. So I was wondering is there subtle difference in the security policy on Fedora that would cause this behaviour? Or perhaps something else entirely? [1] the source set I am build on Fedora is: userspace-rcu -- v0.6.8 lttng-ust -- v2.0.5 lttng-tools -- v2.0.4 babeltrace -- v1.0.0 I tried building from 'master' for all of those modules today but that made no difference and that makes me wonder if it is more of a platform issue as opposed to an LTTng issue. -- andy > > Thanks, > > Mathieu > > * McDermott, Andrew (Andrew.McDermott at windriver.com) wrote: >> >> How often are the LTTng UST packages for Ubuntu updated? >> >> Having done a fresh install I see the version reported as: >> >> $ lttng version >> lttng version 2.0.1 - Annedd'ale >> >> but looking at the git repo I see there is v2.0.4 tag. Are these >> updates only available if built from source? In general I was trying to >> avoid the daily development versions from: >> >> https://launchpad.net/~lttng/+archive/daily. >> >> -- >> andy >> >> _______________________________________________ >> lttng-dev mailing list >> lttng-dev at lists.lttng.org >> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:13 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:13 -0500 Subject: [lttng-dev] [URCU pull request review] urcu improvements Message-ID: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Here is a pull request to myself for my recent work on wfcqueue and urcu flavors into the userspace RCU master branch. Please let me know if you see any immediate show stoppers. List of changes: [PATCH 01/16] Fix: wfcqueue nonblocking dequeue [PATCH 02/16] wfcqueue: enqueue and splice return queue state [PATCH 03/16] test wfcqueue: add tests for queue state return value [PATCH 04/16] urcu-call-rcu: use wait-free splice return value [PATCH 05/16] wfcqueue: document empty criterion [PATCH 06/16] wfcqueue: implement mutex-free splice [PATCH 07/16] urcu-qsbr: improve 2-phase wait scheme [PATCH 08/16] urcu-mb/signal/membarrier: improve 2-phase wait scheme [PATCH 09/16] urcu-bp: improve 2-phase wait scheme [PATCH 10/16] urcu-qsbr: move offline threads to separate list [PATCH 11/16] urcu-mb/signal/membarrier: move quiescent threads to [PATCH 12/16] urcu-bp: move quiescent threads to separate list [PATCH 13/16] tests: use standard malloc/free for synchronize_rcu() [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() [PATCH 15/16] urcu-wait: move wait code into separate file [PATCH 16/16] urcu-wait: move queue management code into urcu-wait.h diffstat: Makefile.am | 2 tests/test_urcu.c | 60 ++------------ tests/test_urcu_bp.c | 59 ++------------ tests/test_urcu_qsbr.c | 61 ++------------- tests/test_urcu_wfcq.c | 131 +++++++++++++++++++++++++------- urcu-bp.c | 88 ++++++++++++++------- urcu-call-rcu-impl.h | 9 +- urcu-qsbr.c | 193 ++++++++++++++++++++++++++++++++++++------------ urcu-wait.h | 184 +++++++++++++++++++++++++++++++++++++++++++++ urcu.c | 95 +++++++++++++++-------- urcu/static/urcu-bp.h | 29 ++++--- urcu/static/urcu-qsbr.h | 14 ++- urcu/static/urcu.h | 15 ++- urcu/static/wfcqueue.h | 133 +++++++++++++++++++++++++-------- urcu/wfcqueue.h | 62 +++++++++++---- wfcqueue.c | 16 +-- 16 files changed, 786 insertions(+), 365 deletions(-) Thanks, Mathieu From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:14 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:14 -0500 Subject: [lttng-dev] [PATCH 01/16] Fix: wfcqueue nonblocking dequeue In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-2-git-send-email-mathieu.desnoyers@efficios.com> Failures were not handled in the nonblocking dequeue implementation. Signed-off-by: Mathieu Desnoyers --- urcu/static/wfcqueue.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 8733771..a284b58 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -312,6 +312,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, return NULL; node = ___cds_wfcq_node_sync_next(&head->node, blocking); + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) + return CDS_WFCQ_WOULDBLOCK; if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { /* @@ -332,6 +334,15 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) return node; next = ___cds_wfcq_node_sync_next(node, blocking); + /* + * In nonblocking mode, if we would need to block to + * get node's next, set the head next node pointer + * (currently NULL) back to its original value. + */ + if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { + head->node.next = node; + return CDS_WFCQ_WOULDBLOCK; + } } /* -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:15 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:15 -0500 Subject: [lttng-dev] [PATCH 02/16] wfcqueue: enqueue and splice return queue state In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-3-git-send-email-mathieu.desnoyers@efficios.com> enqueue can return whether the queue was empty or not prior to enqueue. splice can return this information about destination queue too, but there are more cases to handle, because we don't touch the destination queue if the source queue was empty, and in the nonblocking case, we return that we would need to block on the source queue. The destination queue state is sampled atomically with enqueue/splice to destination operations. Knowing this state is useful when "ownership" on a batch of queue items can be assigned to those enqueuing the first items, e.g. to implement wait/wakeup schemes. Signed-off-by: Mathieu Desnoyers CC: Paul E. McKenney CC: Lai Jiangshan --- urcu/static/wfcqueue.h | 47 ++++++++++++++++++++++++++++++++--------------- urcu/wfcqueue.h | 28 ++++++++++++++++++++++------ wfcqueue.c | 14 +++++++------- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index a284b58..1200227 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -128,7 +128,7 @@ static inline void _cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, assert(!ret); } -static inline void ___cds_wfcq_append(struct cds_wfcq_head *head, +static inline bool ___cds_wfcq_append(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *new_head, struct cds_wfcq_node *new_tail) @@ -152,6 +152,11 @@ static inline void ___cds_wfcq_append(struct cds_wfcq_head *head, * perspective. */ CMM_STORE_SHARED(old_tail->next, new_head); + /* + * Return false if queue was empty prior to adding the node, + * else return true. + */ + return old_tail != &head->node; } /* @@ -159,12 +164,15 @@ static inline void ___cds_wfcq_append(struct cds_wfcq_head *head, * * Issues a full memory barrier before enqueue. No mutual exclusion is * required. + * + * Returns false if the queue was empty prior to adding the node. + * Returns true otherwise. */ -static inline void _cds_wfcq_enqueue(struct cds_wfcq_head *head, +static inline bool _cds_wfcq_enqueue(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *new_tail) { - ___cds_wfcq_append(head, tail, new_tail, new_tail); + return ___cds_wfcq_append(head, tail, new_tail, new_tail); } /* @@ -384,7 +392,7 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, return ___cds_wfcq_dequeue(head, tail, 0); } -static inline int +static inline enum cds_wfcq_ret ___cds_wfcq_splice( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, @@ -395,11 +403,11 @@ ___cds_wfcq_splice( struct cds_wfcq_node *head, *tail; if (_cds_wfcq_empty(src_q_head, src_q_tail)) - return 0; + return CDS_WFCQ_RET_SRC_EMPTY; head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); if (head == CDS_WFCQ_WOULDBLOCK) - return -1; + return CDS_WFCQ_RET_WOULDBLOCK; _cds_wfcq_node_init(&src_q_head->node); /* @@ -414,8 +422,10 @@ ___cds_wfcq_splice( * Append the spliced content of src_q into dest_q. Does not * require mutual exclusion on dest_q (wait-free). */ - ___cds_wfcq_append(dest_q_head, dest_q_tail, head, tail); - return 0; + if (___cds_wfcq_append(dest_q_head, dest_q_tail, head, tail)) + return CDS_WFCQ_RET_DEST_NON_EMPTY; + else + return CDS_WFCQ_RET_DEST_EMPTY; } @@ -426,25 +436,27 @@ ___cds_wfcq_splice( * dest_q must be already initialized. * Dequeue/splice/iteration mutual exclusion for src_q should be ensured * by the caller. + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. */ -static inline void +static inline enum cds_wfcq_ret ___cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { - (void) ___cds_wfcq_splice(dest_q_head, dest_q_tail, + return ___cds_wfcq_splice(dest_q_head, dest_q_tail, src_q_head, src_q_tail, 1); } /* * __cds_wfcq_splice_nonblocking: enqueue all src_q nodes at the end of dest_q. * - * Same as __cds_wfcq_splice_blocking, but returns nonzero if it needs to - * block. + * Same as __cds_wfcq_splice_blocking, but returns + * CDS_WFCQ_RET_WOULDBLOCK if it needs to block. */ -static inline int +static inline enum cds_wfcq_ret ___cds_wfcq_splice_nonblocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, @@ -485,18 +497,23 @@ _cds_wfcq_dequeue_blocking(struct cds_wfcq_head *head, * consistent, but no other memory ordering is ensured. * Mutual exlusion with cds_wfcq_dequeue_blocking and dequeue lock is * ensured. + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. */ -static inline void +static inline enum cds_wfcq_ret _cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { + enum cds_wfcq_ret ret; + _cds_wfcq_dequeue_lock(src_q_head, src_q_tail); - ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, + ret = ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, src_q_head, src_q_tail); _cds_wfcq_dequeue_unlock(src_q_head, src_q_tail); + return ret; } #ifdef __cplusplus diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h index fe2862e..ddf6b87 100644 --- a/urcu/wfcqueue.h +++ b/urcu/wfcqueue.h @@ -45,6 +45,13 @@ extern "C" { #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) +enum cds_wfcq_ret { + CDS_WFCQ_RET_WOULDBLOCK = -1, + CDS_WFCQ_RET_DEST_EMPTY = 0, + CDS_WFCQ_RET_DEST_NON_EMPTY = 1, + CDS_WFCQ_RET_SRC_EMPTY = 2, +}; + struct cds_wfcq_node { struct cds_wfcq_node *next; }; @@ -156,8 +163,11 @@ extern void cds_wfcq_dequeue_unlock(struct cds_wfcq_head *head, * * Issues a full memory barrier before enqueue. No mutual exclusion is * required. + * + * Returns false if the queue was empty prior to adding the node. + * Returns true otherwise. */ -extern void cds_wfcq_enqueue(struct cds_wfcq_head *head, +extern bool cds_wfcq_enqueue(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *node); @@ -183,8 +193,11 @@ extern struct cds_wfcq_node *cds_wfcq_dequeue_blocking( * consistent, but no other memory ordering is ensured. * Mutual exlusion with cds_wfcq_dequeue_blocking and dequeue lock is * ensured. + * + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Cannot block. */ -extern void cds_wfcq_splice_blocking( +extern enum cds_wfcq_ret cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, @@ -222,8 +235,11 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( * consistent, but no other memory ordering is ensured. * Dequeue/splice/iteration mutual exclusion for src_q should be ensured * by the caller. + * + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. Cannot block. */ -extern void __cds_wfcq_splice_blocking( +extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, @@ -232,10 +248,10 @@ extern void __cds_wfcq_splice_blocking( /* * __cds_wfcq_splice_nonblocking: enqueue all src_q nodes at the end of dest_q. * - * Same as __cds_wfcq_splice_blocking, but returns nonzero if it needs to - * block. + * Same as __cds_wfcq_splice_blocking, but returns + * CDS_WFCQ_RET_WOULDBLOCK if it needs to block. */ -extern int __cds_wfcq_splice_nonblocking( +extern enum cds_wfcq_ret __cds_wfcq_splice_nonblocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, diff --git a/wfcqueue.c b/wfcqueue.c index 90b810e..207df95 100644 --- a/wfcqueue.c +++ b/wfcqueue.c @@ -47,11 +47,11 @@ bool cds_wfcq_empty(struct cds_wfcq_head *head, return _cds_wfcq_empty(head, tail); } -void cds_wfcq_enqueue(struct cds_wfcq_head *head, +bool cds_wfcq_enqueue(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail, struct cds_wfcq_node *node) { - _cds_wfcq_enqueue(head, tail, node); + return _cds_wfcq_enqueue(head, tail, node); } void cds_wfcq_dequeue_lock(struct cds_wfcq_head *head, @@ -73,13 +73,13 @@ struct cds_wfcq_node *cds_wfcq_dequeue_blocking( return _cds_wfcq_dequeue_blocking(head, tail); } -void cds_wfcq_splice_blocking( +enum cds_wfcq_ret cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { - _cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, + return _cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, src_q_head, src_q_tail); } @@ -97,17 +97,17 @@ struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( return ___cds_wfcq_dequeue_nonblocking(head, tail); } -void __cds_wfcq_splice_blocking( +enum cds_wfcq_ret __cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, struct cds_wfcq_tail *src_q_tail) { - ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, + return ___cds_wfcq_splice_blocking(dest_q_head, dest_q_tail, src_q_head, src_q_tail); } -int __cds_wfcq_splice_nonblocking( +enum cds_wfcq_ret __cds_wfcq_splice_nonblocking( struct cds_wfcq_head *dest_q_head, struct cds_wfcq_tail *dest_q_tail, struct cds_wfcq_head *src_q_head, -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:17 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:17 -0500 Subject: [lttng-dev] [PATCH 04/16] urcu-call-rcu: use wait-free splice return value In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-5-git-send-email-mathieu.desnoyers@efficios.com> We can now use the splice return value to know if the source queue was empty rather than testing for destination queue emptiness after the splice operation. Signed-off-by: Mathieu Desnoyers --- urcu-call-rcu-impl.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index 5dfdb92..6580397 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -252,11 +252,14 @@ static void *call_rcu_thread(void *arg) struct cds_wfcq_head cbs_tmp_head; struct cds_wfcq_tail cbs_tmp_tail; struct cds_wfcq_node *cbs, *cbs_tmp_n; + enum cds_wfcq_ret splice_ret; cds_wfcq_init(&cbs_tmp_head, &cbs_tmp_tail); - __cds_wfcq_splice_blocking(&cbs_tmp_head, &cbs_tmp_tail, - &crdp->cbs_head, &crdp->cbs_tail); - if (!cds_wfcq_empty(&cbs_tmp_head, &cbs_tmp_tail)) { + splice_ret = __cds_wfcq_splice_blocking(&cbs_tmp_head, + &cbs_tmp_tail, &crdp->cbs_head, &crdp->cbs_tail); + assert(splice_ret != CDS_WFCQ_RET_WOULDBLOCK); + assert(splice_ret != CDS_WFCQ_RET_DEST_NON_EMPTY); + if (splice_ret != CDS_WFCQ_RET_SRC_EMPTY) { synchronize_rcu(); cbcount = 0; __cds_wfcq_for_each_blocking_safe(&cbs_tmp_head, -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:16 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:16 -0500 Subject: [lttng-dev] [PATCH 03/16] test wfcqueue: add tests for queue state return value In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-4-git-send-email-mathieu.desnoyers@efficios.com> with e.g. ./test_urcu_wfcq 2 2 10 -w we can confirm that we see as many "enqueue to empty queue" as we see "splice from non-empty queue", which confirms that the queue state returned by enqueue is indeed sampled atomically with enqueue. Signed-off-by: Mathieu Desnoyers CC: Paul E. McKenney CC: Lai Jiangshan --- tests/test_urcu_wfcq.c | 131 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 103 insertions(+), 28 deletions(-) diff --git a/tests/test_urcu_wfcq.c b/tests/test_urcu_wfcq.c index f90fc14..ccd5cf1 100644 --- a/tests/test_urcu_wfcq.c +++ b/tests/test_urcu_wfcq.c @@ -75,7 +75,7 @@ enum test_sync { static enum test_sync test_sync; -static volatile int test_go, test_stop; +static volatile int test_go, test_stop_enqueue, test_stop_dequeue; static unsigned long rduration; @@ -92,7 +92,8 @@ static inline void loop_sleep(unsigned long loops) static int verbose_mode; -static int test_dequeue, test_splice; +static int test_dequeue, test_splice, test_wait_empty; +static int test_enqueue_stopped; #define printf_verbose(fmt, args...) \ do { \ @@ -150,12 +151,12 @@ static void set_affinity(void) */ static int test_duration_dequeue(void) { - return !test_stop; + return !test_stop_dequeue; } static int test_duration_enqueue(void) { - return !test_stop; + return !test_stop_enqueue; } static DEFINE_URCU_TLS(unsigned long long, nr_dequeues); @@ -163,6 +164,8 @@ static DEFINE_URCU_TLS(unsigned long long, nr_enqueues); static DEFINE_URCU_TLS(unsigned long long, nr_successful_dequeues); static DEFINE_URCU_TLS(unsigned long long, nr_successful_enqueues); +static DEFINE_URCU_TLS(unsigned long long, nr_empty_dest_enqueues); +static DEFINE_URCU_TLS(unsigned long long, nr_splice); static unsigned int nr_enqueuers; static unsigned int nr_dequeuers; @@ -173,6 +176,7 @@ static struct cds_wfcq_tail __attribute__((aligned(CAA_CACHE_LINE_SIZE))) tail; static void *thr_enqueuer(void *_count) { unsigned long long *count = _count; + bool was_nonempty; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "enqueuer", (unsigned long) pthread_self(), @@ -190,8 +194,10 @@ static void *thr_enqueuer(void *_count) if (!node) goto fail; cds_wfcq_node_init(node); - cds_wfcq_enqueue(&head, &tail, node); + was_nonempty = cds_wfcq_enqueue(&head, &tail, node); URCU_TLS(nr_successful_enqueues)++; + if (!was_nonempty) + URCU_TLS(nr_empty_dest_enqueues)++; if (caa_unlikely(wdelay)) loop_sleep(wdelay); @@ -201,13 +207,18 @@ fail: break; } + uatomic_inc(&test_enqueue_stopped); count[0] = URCU_TLS(nr_enqueues); count[1] = URCU_TLS(nr_successful_enqueues); + count[2] = URCU_TLS(nr_empty_dest_enqueues); printf_verbose("enqueuer thread_end, thread id : %lx, tid %lu, " - "enqueues %llu successful_enqueues %llu\n", + "enqueues %llu successful_enqueues %llu, " + "empty_dest_enqueues %llu\n", pthread_self(), (unsigned long) gettid(), - URCU_TLS(nr_enqueues), URCU_TLS(nr_successful_enqueues)); + URCU_TLS(nr_enqueues), + URCU_TLS(nr_successful_enqueues), + URCU_TLS(nr_empty_dest_enqueues)); return ((void*)1); } @@ -233,16 +244,33 @@ static void do_test_splice(enum test_sync sync) struct cds_wfcq_head tmp_head; struct cds_wfcq_tail tmp_tail; struct cds_wfcq_node *node, *n; + enum cds_wfcq_ret ret; cds_wfcq_init(&tmp_head, &tmp_tail); if (sync == TEST_SYNC_MUTEX) - cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, + ret = cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, &head, &tail); else - __cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, + ret = __cds_wfcq_splice_blocking(&tmp_head, &tmp_tail, &head, &tail); + switch (ret) { + case CDS_WFCQ_RET_WOULDBLOCK: + assert(0); /* blocking call */ + break; + case CDS_WFCQ_RET_DEST_EMPTY: + URCU_TLS(nr_splice)++; + /* ok */ + break; + case CDS_WFCQ_RET_DEST_NON_EMPTY: + assert(0); /* entirely unexpected */ + break; + case CDS_WFCQ_RET_SRC_EMPTY: + /* ok, we could even skip iteration on dest if we wanted */ + break; + } + __cds_wfcq_for_each_blocking_safe(&tmp_head, &tmp_tail, node, n) { free(node); URCU_TLS(nr_successful_dequeues)++; @@ -286,12 +314,15 @@ static void *thr_dequeuer(void *_count) } printf_verbose("dequeuer thread_end, thread id : %lx, tid %lu, " - "dequeues %llu, successful_dequeues %llu\n", + "dequeues %llu, successful_dequeues %llu, " + "nr_splice %llu\n", pthread_self(), (unsigned long) gettid(), - URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues)); + URCU_TLS(nr_dequeues), URCU_TLS(nr_successful_dequeues), + URCU_TLS(nr_splice)); count[0] = URCU_TLS(nr_dequeues); count[1] = URCU_TLS(nr_successful_dequeues); + count[2] = URCU_TLS(nr_splice); return ((void*)2); } @@ -320,6 +351,7 @@ static void show_usage(int argc, char **argv) printf(" [-M] (use mutex external synchronization)"); printf(" [-0] (use no external synchronization)"); printf(" Note: default: mutex external synchronization used."); + printf(" [-w] Wait for dequeuer to empty queue"); printf("\n"); } @@ -331,9 +363,11 @@ int main(int argc, char **argv) unsigned long long *count_enqueuer, *count_dequeuer; unsigned long long tot_enqueues = 0, tot_dequeues = 0; unsigned long long tot_successful_enqueues = 0, - tot_successful_dequeues = 0; + tot_successful_dequeues = 0, + tot_empty_dest_enqueues = 0, + tot_splice = 0; unsigned long long end_dequeues = 0; - int i, a; + int i, a, retval = 0; if (argc < 4) { show_usage(argc, argv); @@ -401,6 +435,9 @@ int main(int argc, char **argv) case '0': test_sync = TEST_SYNC_NONE; break; + case 'w': + test_wait_empty = 1; + break; } } @@ -419,6 +456,8 @@ int main(int argc, char **argv) printf_verbose("External sync: mutex.\n"); else printf_verbose("External sync: none.\n"); + if (test_wait_empty) + printf_verbose("Wait for dequeuers to empty queue.\n"); printf_verbose("Writer delay : %lu loops.\n", rduration); printf_verbose("Reader duration : %lu loops.\n", wdelay); printf_verbose("thread %-6s, thread id : %lx, tid %lu\n", @@ -427,21 +466,21 @@ int main(int argc, char **argv) tid_enqueuer = malloc(sizeof(*tid_enqueuer) * nr_enqueuers); tid_dequeuer = malloc(sizeof(*tid_dequeuer) * nr_dequeuers); - count_enqueuer = malloc(2 * sizeof(*count_enqueuer) * nr_enqueuers); - count_dequeuer = malloc(2 * sizeof(*count_dequeuer) * nr_dequeuers); + count_enqueuer = malloc(3 * sizeof(*count_enqueuer) * nr_enqueuers); + count_dequeuer = malloc(3 * sizeof(*count_dequeuer) * nr_dequeuers); cds_wfcq_init(&head, &tail); next_aff = 0; for (i = 0; i < nr_enqueuers; i++) { err = pthread_create(&tid_enqueuer[i], NULL, thr_enqueuer, - &count_enqueuer[2 * i]); + &count_enqueuer[3 * i]); if (err != 0) exit(1); } for (i = 0; i < nr_dequeuers; i++) { err = pthread_create(&tid_dequeuer[i], NULL, thr_dequeuer, - &count_dequeuer[2 * i]); + &count_dequeuer[3 * i]); if (err != 0) exit(1); } @@ -456,21 +495,34 @@ int main(int argc, char **argv) write (1, ".", 1); } - test_stop = 1; + test_stop_enqueue = 1; + + if (test_wait_empty) { + while (nr_enqueuers != uatomic_read(&test_enqueue_stopped)) { + sleep(1); + } + while (!cds_wfcq_empty(&head, &tail)) { + sleep(1); + } + } + + test_stop_dequeue = 1; for (i = 0; i < nr_enqueuers; i++) { err = pthread_join(tid_enqueuer[i], &tret); if (err != 0) exit(1); - tot_enqueues += count_enqueuer[2 * i]; - tot_successful_enqueues += count_enqueuer[2 * i + 1]; + tot_enqueues += count_enqueuer[3 * i]; + tot_successful_enqueues += count_enqueuer[3 * i + 1]; + tot_empty_dest_enqueues += count_enqueuer[3 * i + 2]; } for (i = 0; i < nr_dequeuers; i++) { err = pthread_join(tid_dequeuer[i], &tret); if (err != 0) exit(1); - tot_dequeues += count_dequeuer[2 * i]; - tot_successful_dequeues += count_dequeuer[2 * i + 1]; + tot_dequeues += count_dequeuer[3 * i]; + tot_successful_dequeues += count_dequeuer[3 * i + 1]; + tot_splice += count_dequeuer[3 * i + 2]; } test_end(&end_dequeues); @@ -478,27 +530,50 @@ int main(int argc, char **argv) printf_verbose("total number of enqueues : %llu, dequeues %llu\n", tot_enqueues, tot_dequeues); printf_verbose("total number of successful enqueues : %llu, " - "successful dequeues %llu\n", - tot_successful_enqueues, tot_successful_dequeues); + "enqueues to empty dest : %llu, " + "successful dequeues %llu, ", + "splice : %llu\n", + tot_successful_enqueues, + tot_empty_dest_enqueues, + tot_successful_dequeues, + tot_splice); printf("SUMMARY %-25s testdur %4lu nr_enqueuers %3u wdelay %6lu " "nr_dequeuers %3u " "rdur %6lu nr_enqueues %12llu nr_dequeues %12llu " - "successful enqueues %12llu successful dequeues %12llu " + "successful enqueues %12llu enqueues to empty dest %12llu " + "successful dequeues %12llu splice %12llu " "end_dequeues %llu nr_ops %12llu\n", argv[0], duration, nr_enqueuers, wdelay, nr_dequeuers, rduration, tot_enqueues, tot_dequeues, tot_successful_enqueues, - tot_successful_dequeues, end_dequeues, + tot_empty_dest_enqueues, + tot_successful_dequeues, tot_splice, end_dequeues, tot_enqueues + tot_dequeues); - if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) + + if (tot_successful_enqueues != tot_successful_dequeues + end_dequeues) { printf("WARNING! Discrepancy between nr succ. enqueues %llu vs " "succ. dequeues + end dequeues %llu.\n", tot_successful_enqueues, tot_successful_dequeues + end_dequeues); + retval = 1; + } + /* + * If only using splice to dequeue, the enqueuer should see + * exactly as many empty queues than the number of non-empty + * src splice. + */ + if (test_wait_empty && test_splice && !test_dequeue + && tot_empty_dest_enqueues != tot_splice) { + printf("WARNING! Discrepancy between empty enqueue (%llu) and " + "number of non-empty splice (%llu)\n", + tot_empty_dest_enqueues, + tot_splice); + retval = 1; + } free(count_enqueuer); free(count_dequeuer); free(tid_enqueuer); free(tid_dequeuer); - return 0; + return retval; } -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:18 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:18 -0500 Subject: [lttng-dev] [PATCH 05/16] wfcqueue: document empty criterion In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-6-git-send-email-mathieu.desnoyers@efficios.com> Signed-off-by: Mathieu Desnoyers --- urcu/static/wfcqueue.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 1200227..8774c03 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -95,6 +95,13 @@ static inline void _cds_wfcq_init(struct cds_wfcq_head *head, * cds_wfcq_empty: return whether wait-free queue is empty. * * No memory barrier is issued. No mutual exclusion is required. + * + * We perform the test on head->node.next to check if the queue is + * possibly empty, but we confirm this by checking if the tail pointer + * points to the head node because the tail pointer is the linearisation + * point of the enqueuers. Just checking the head next pointer could + * make a queue appear empty if an enqueuer is preempted for a long time + * between xchg() and setting the previous node's next pointer. */ static inline bool _cds_wfcq_empty(struct cds_wfcq_head *head, struct cds_wfcq_tail *tail) -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:20 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:20 -0500 Subject: [lttng-dev] [PATCH 07/16] urcu-qsbr: improve 2-phase wait scheme In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-8-git-send-email-mathieu.desnoyers@efficios.com> In the single-bit, 2-phase grace period scheme, all we need to do is to observe each reader going through a quiescent state while we are in the grace period. We therefore only need to perform one global counter update, surrounded by 2 iterations on readers to observe change in their snapshot. We can therefore remove the first counter update (prior to the first iteration on readers): it was useless and was only slowing down the grace period. Suggested-by: Alan Stern CC: Paul E. McKenney CC: Lai Jiangshan Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 92 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index c6a1b18..eb167d1 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -116,38 +116,16 @@ static void wait_gp(void) NULL, NULL, 0); } -static void update_counter_and_wait(void) +static void wait_for_readers(void) { CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; -#if (CAA_BITS_PER_LONG < 64) - /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR); -#else /* !(CAA_BITS_PER_LONG < 64) */ - /* Increment current G.P. */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR); -#endif /* !(CAA_BITS_PER_LONG < 64) */ - - /* - * Must commit rcu_gp_ctr update to memory before waiting for - * quiescent state. Failure to do so could result in the writer - * waiting forever while new readers are always accessing data - * (no progress). Enforce compiler-order of store to rcu_gp_ctr - * before load URCU_TLS(rcu_reader).ctr. - */ - cmm_barrier(); - - /* - * Adding a cmm_smp_mb() which is _not_ formally required, but makes the - * model easier to understand. It does not have a big performance impact - * anyway, given this is the write-side. - */ - cmm_smp_mb(); - /* - * Wait for each thread rcu_reader_qs_gp count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr to either + * indicate quiescence (offline), or for them to observe the + * current rcu_gp_ctr value. */ for (;;) { wait_loops++; @@ -223,17 +201,17 @@ void synchronize_rcu(void) goto out; /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe original parity or be quiescent. */ - update_counter_and_wait(); /* 0 -> 1, wait readers in parity 0 */ + wait_for_readers(); /* - * Must finish waiting for quiescent state for parity 0 before - * committing next rcu_gp_ctr update to memory. Failure to - * do so could result in the writer waiting forever while new + * Must finish waiting for quiescent state for original parity + * before committing next rcu_gp_ctr update to memory. Failure + * to do so could result in the writer waiting forever while new * readers are always accessing data (no progress). Enforce - * compiler-order of load URCU_TLS(rcu_reader).ctr before store to - * rcu_gp_ctr. + * compiler-order of load URCU_TLS(rcu_reader).ctr before store + * to rcu_gp_ctr. */ cmm_barrier(); @@ -244,10 +222,29 @@ void synchronize_rcu(void) */ cmm_smp_mb(); + /* Switch parity: 0 -> 1, 1 -> 0 */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR); + /* - * Wait for previous parity to be empty of readers. + * Must commit rcu_gp_ctr update to memory before waiting for + * quiescent state. Failure to do so could result in the writer + * waiting forever while new readers are always accessing data + * (no progress). Enforce compiler-order of store to rcu_gp_ctr + * before load URCU_TLS(rcu_reader).ctr. */ - update_counter_and_wait(); /* 1 -> 0, wait readers in parity 1 */ + cmm_barrier(); + + /* + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + + /* + * Wait for readers to observe new parity or be quiescent. + */ + wait_for_readers(); out: mutex_unlock(&rcu_gp_lock); @@ -280,7 +277,30 @@ void synchronize_rcu(void) mutex_lock(&rcu_gp_lock); if (cds_list_empty(®istry)) goto out; - update_counter_and_wait(); + + /* Increment current G.P. */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr + RCU_GP_CTR); + + /* + * Must commit rcu_gp_ctr update to memory before waiting for + * quiescent state. Failure to do so could result in the writer + * waiting forever while new readers are always accessing data + * (no progress). Enforce compiler-order of store to rcu_gp_ctr + * before load URCU_TLS(rcu_reader).ctr. + */ + cmm_barrier(); + + /* + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + + /* + * Wait for readers to observe new count of be quiescent. + */ + wait_for_readers(); out: mutex_unlock(&rcu_gp_lock); -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:19 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:19 -0500 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> A carefully crafted splice operation does not need to use an external mutex to synchronize against other splice operations. The trick is atomically exchange the head next pointer with NULL. If the pointer we replaced was NULL, it means the queue was possibly empty. If head next was not NULL, by setting head to NULL, we ensure that concurrent splice operations are going to see an empty queue, even if concurrent enqueue operations move tail further. This means that as long as we are within splice, after setting head to NULL, but before moving tail back to head, concurrent splice operations will always see an empty queue, therefore acting as mutual exclusion. If exchange returns a NULL head, we confirm that it was indeed empty by checking if the tail pointer points to the head node, busy-waiting if necessary. Then the last step is to move the tail pointer to head. At that point, enqueuers are going to start enqueuing at head again, and other splice operations will be able to proceed. Signed-off-by: Mathieu Desnoyers --- urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ urcu/wfcqueue.h | 40 ++++++++++++++++++---------- wfcqueue.c | 2 +- 3 files changed, 79 insertions(+), 31 deletions(-) diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h index 8774c03..4b2de50 100644 --- a/urcu/static/wfcqueue.h +++ b/urcu/static/wfcqueue.h @@ -46,15 +46,30 @@ extern "C" { * half-wait-free/half-blocking queue implementation done by Paul E. * McKenney. * - * Mutual exclusion of __cds_wfcq_* API - * - * Unless otherwise stated, the caller must ensure mutual exclusion of - * queue update operations "dequeue" and "splice" (for source queue). - * Queue read operations "first" and "next", which are used by - * "for_each" iterations, need to be protected against concurrent - * "dequeue" and "splice" (for source queue) by the caller. - * "enqueue", "splice" (for destination queue), and "empty" are the only - * operations that can be used without any mutual exclusion. + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API + * + * Synchronization table: + * + * External synchronization techniques described in the API below is + * required between pairs marked with "X". No external synchronization + * required between pairs marked with "-". + * + * Legend: + * [1] cds_wfcq_enqueue + * [2] __cds_wfcq_splice (destination queue) + * [3] __cds_wfcq_dequeue + * [4] __cds_wfcq_splice (source queue) + * [5] __cds_wfcq_first + * [6] __cds_wfcq_next + * + * [1] [2] [3] [4] [5] [6] + * [1] - - - - - - + * [2] - - - - - - + * [3] - - X X X X + * [4] - - X - X X + * [5] - - X X - - + * [6] - - X X - - + * * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). * * For convenience, cds_wfcq_dequeue_blocking() and @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, return ___cds_wfcq_dequeue(head, tail, 0); } +/* + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. + * + * Dequeue all nodes from src_q. + * dest_q must be already initialized. + * Mutual exclusion for src_q should be ensured by the caller as + * specified in the "Synchronisation table". + * Returns enum cds_wfcq_ret which indicates the state of the src or + * dest queue. + */ static inline enum cds_wfcq_ret ___cds_wfcq_splice( struct cds_wfcq_head *dest_q_head, @@ -408,14 +433,26 @@ ___cds_wfcq_splice( int blocking) { struct cds_wfcq_node *head, *tail; + int attempt = 0; if (_cds_wfcq_empty(src_q_head, src_q_tail)) return CDS_WFCQ_RET_SRC_EMPTY; - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); - if (head == CDS_WFCQ_WOULDBLOCK) - return CDS_WFCQ_RET_WOULDBLOCK; - _cds_wfcq_node_init(&src_q_head->node); + for (;;) { + head = uatomic_xchg(&src_q_head->node.next, NULL); + if (head) + break; /* non-empty */ + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) + return CDS_WFCQ_RET_SRC_EMPTY; + if (!blocking) + return CDS_WFCQ_RET_WOULDBLOCK; + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ + attempt = 0; + } else { + caa_cpu_relax(); + } + } /* * Memory barrier implied before uatomic_xchg() orders store to @@ -435,14 +472,13 @@ ___cds_wfcq_splice( return CDS_WFCQ_RET_DEST_EMPTY; } - /* * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. * * Dequeue all nodes from src_q. * dest_q must be already initialized. - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured - * by the caller. + * Mutual exclusion for src_q should be ensured by the caller as + * specified in the "Synchronisation table". * Returns enum cds_wfcq_ret which indicates the state of the src or * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. */ diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h index ddf6b87..d9ec534 100644 --- a/urcu/wfcqueue.h +++ b/urcu/wfcqueue.h @@ -46,7 +46,7 @@ extern "C" { #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) enum cds_wfcq_ret { - CDS_WFCQ_RET_WOULDBLOCK = -1, + CDS_WFCQ_RET_WOULDBLOCK = -1, CDS_WFCQ_RET_DEST_EMPTY = 0, CDS_WFCQ_RET_DEST_NON_EMPTY = 1, CDS_WFCQ_RET_SRC_EMPTY = 2, @@ -110,13 +110,28 @@ struct cds_wfcq_tail { /* * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API * - * Unless otherwise stated, the caller must ensure mutual exclusion of - * queue update operations "dequeue" and "splice" (for source queue). - * Queue read operations "first" and "next", which are used by - * "for_each" iterations, need to be protected against concurrent - * "dequeue" and "splice" (for source queue) by the caller. - * "enqueue", "splice" (for destination queue), and "empty" are the only - * operations that can be used without any mutual exclusion. + * Synchronization table: + * + * External synchronization techniques described in the API below is + * required between pairs marked with "X". No external synchronization + * required between pairs marked with "-". + * + * Legend: + * [1] cds_wfcq_enqueue + * [2] __cds_wfcq_splice (destination queue) + * [3] __cds_wfcq_dequeue + * [4] __cds_wfcq_splice (source queue) + * [5] __cds_wfcq_first + * [6] __cds_wfcq_next + * + * [1] [2] [3] [4] [5] [6] + * [1] - - - - - - + * [2] - - - - - - + * [3] - - X X X X + * [4] - - X - X X + * [5] - - X X - - + * [6] - - X X - - + * * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). * * For convenience, cds_wfcq_dequeue_blocking() and @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( * * Dequeue all nodes from src_q. * dest_q must be already initialized. - * Content written into the node before enqueue is guaranteed to be - * consistent, but no other memory ordering is ensured. - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured - * by the caller. - * + * Mutual exclusion for src_q should be ensured by the caller as + * specified in the "Synchronisation table". * Returns enum cds_wfcq_ret which indicates the state of the src or - * dest queue. Cannot block. + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. */ extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( struct cds_wfcq_head *dest_q_head, diff --git a/wfcqueue.c b/wfcqueue.c index 207df95..ab0eb93 100644 --- a/wfcqueue.c +++ b/wfcqueue.c @@ -1,7 +1,7 @@ /* * wfcqueue.c * - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue * * Copyright 2010-2012 - Mathieu Desnoyers * Copyright 2011-2012 - Lai Jiangshan -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:22 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:22 -0500 Subject: [lttng-dev] [PATCH 09/16] urcu-bp: improve 2-phase wait scheme In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-10-git-send-email-mathieu.desnoyers@efficios.com> In the single-bit, 2-phase grace period scheme, all we need to do is to observe each reader going through a quiescent state while we are in the grace period. We therefore only need to perform one global counter update, surrounded by 2 iterations on readers to observe change in their snapshot. We can therefore remove the first counter update (prior to the first iteration on readers): it was useless and was only slowing down the grace period. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-bp.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/urcu-bp.c b/urcu-bp.c index b07a1bb..4b3cf01 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -164,31 +164,16 @@ static void mutex_unlock(pthread_mutex_t *mutex) urcu_die(ret); } -static void update_counter_and_wait(void) +static void wait_for_readers(void) { CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; - /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); - - /* - * Must commit qparity update to memory before waiting for other parity - * quiescent state. Failure to do so could result in the writer waiting - * forever while new readers are always accessing data (no progress). - * Ensured by CMM_STORE_SHARED and CMM_LOAD_SHARED. - */ - - /* - * Adding a cmm_smp_mb() which is _not_ formally required, but makes the - * model easier to understand. It does not have a big performance impact - * anyway, given this is the write-side. - */ - cmm_smp_mb(); - /* - * Wait for each thread rcu_reader.ctr count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr to either + * indicate quiescence (not nested), or observe the current + * rcu_gp_ctr value. */ for (;;) { wait_loops++; @@ -234,9 +219,26 @@ void synchronize_rcu(void) rcu_gc_registry(); /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe original parity or be quiescent. + */ + wait_for_readers(); + + /* + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + + /* Switch parity: 0 -> 1, 1 -> 0 */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); + + /* + * Must commit qparity update to memory before waiting for other parity + * quiescent state. Failure to do so could result in the writer waiting + * forever while new readers are always accessing data (no progress). + * Ensured by CMM_STORE_SHARED and CMM_LOAD_SHARED. */ - update_counter_and_wait(); /* 0 -> 1, wait readers in parity 0 */ /* * Adding a cmm_smp_mb() which is _not_ formally required, but makes the @@ -246,9 +248,9 @@ void synchronize_rcu(void) cmm_smp_mb(); /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe new parity or be quiescent. */ - update_counter_and_wait(); /* 1 -> 0, wait readers in parity 1 */ + wait_for_readers(); /* * Finish waiting for reader threads before letting the old ptr being -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:23 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:23 -0500 Subject: [lttng-dev] [PATCH 10/16] urcu-qsbr: move offline threads to separate list In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-11-git-send-email-mathieu.desnoyers@efficios.com> Accelerate 2-phase grace period by not having to iterate on offline threads twice. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 54 ++++++++++++++++++++++++++++++++++++----------- urcu/static/urcu-qsbr.h | 14 ++++++++++-- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index eb167d1..5b341b5 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -116,9 +116,10 @@ static void wait_gp(void) NULL, NULL, 0); } -static void wait_for_readers(void) +static void wait_for_readers(struct cds_list_head *input_readers, + struct cds_list_head *cur_snap_readers, + struct cds_list_head *qsreaders) { - CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; @@ -136,18 +137,36 @@ static void wait_for_readers(void) * reads them in the opposite order). */ cmm_smp_wmb(); - cds_list_for_each_entry(index, ®istry, node) { + cds_list_for_each_entry(index, input_readers, node) { _CMM_STORE_SHARED(index->waiting, 1); } /* Write futex before read reader_gp */ cmm_smp_mb(); } - cds_list_for_each_entry_safe(index, tmp, ®istry, node) { - if (!rcu_gp_ongoing(&index->ctr)) - cds_list_move(&index->node, &qsreaders); + cds_list_for_each_entry_safe(index, tmp, input_readers, node) { + switch (rcu_reader_state(&index->ctr)) { + case RCU_READER_ACTIVE_CURRENT: + if (cur_snap_readers) { + cds_list_move(&index->node, + cur_snap_readers); + break; + } + /* Fall-through */ + case RCU_READER_INACTIVE: + cds_list_move(&index->node, qsreaders); + break; + case RCU_READER_ACTIVE_OLD: + /* + * Old snapshot. Leaving node in + * input_readers will make us busy-loop + * until the snapshot becomes current or + * the reader becomes inactive. + */ + break; + } } - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { if (wait_loops >= RCU_QS_ACTIVE_ATTEMPTS) { /* Read reader_gp before write futex */ cmm_smp_mb(); @@ -166,8 +185,6 @@ static void wait_for_readers(void) } } } - /* put back the reader list in the registry */ - cds_list_splice(&qsreaders, ®istry); } /* @@ -178,6 +195,8 @@ static void wait_for_readers(void) #if (CAA_BITS_PER_LONG < 64) void synchronize_rcu(void) { + CDS_LIST_HEAD(cur_snap_readers); + CDS_LIST_HEAD(qsreaders); unsigned long was_online; was_online = URCU_TLS(rcu_reader).ctr; @@ -203,7 +222,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe original parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders); /* * Must finish waiting for quiescent state for original parity @@ -244,7 +263,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); out: mutex_unlock(&rcu_gp_lock); @@ -260,6 +284,7 @@ out: #else /* !(CAA_BITS_PER_LONG < 64) */ void synchronize_rcu(void) { + CDS_LIST_HEAD(qsreaders); unsigned long was_online; was_online = URCU_TLS(rcu_reader).ctr; @@ -300,7 +325,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new count of be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); out: mutex_unlock(&rcu_gp_lock); diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h index f314956..f6e5580 100644 --- a/urcu/static/urcu-qsbr.h +++ b/urcu/static/urcu-qsbr.h @@ -62,6 +62,12 @@ extern "C" { #define rcu_assert(args...) #endif +enum rcu_state { + RCU_READER_ACTIVE_CURRENT, + RCU_READER_ACTIVE_OLD, + RCU_READER_INACTIVE, +}; + #ifdef DEBUG_YIELD #include #include @@ -149,12 +155,16 @@ static inline void wake_up_gp(void) } } -static inline int rcu_gp_ongoing(unsigned long *ctr) +static inline enum rcu_state rcu_reader_state(unsigned long *ctr) { unsigned long v; v = CMM_LOAD_SHARED(*ctr); - return v && (v != rcu_gp_ctr); + if (!v) + return RCU_READER_INACTIVE; + if (v == rcu_gp_ctr) + return RCU_READER_ACTIVE_CURRENT; + return RCU_READER_ACTIVE_OLD; } /* -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:21 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:21 -0500 Subject: [lttng-dev] [PATCH 08/16] urcu-mb/signal/membarrier: improve 2-phase wait scheme In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-9-git-send-email-mathieu.desnoyers@efficios.com> In the single-bit, 2-phase grace period scheme, all we need to do is to observe each reader going through a quiescent state while we are in the grace period. We therefore only need to perform one global counter update, surrounded by 2 iterations on readers to observe change in their snapshot. We can therefore remove the first counter update (prior to the first iteration on readers): it was useless and was only slowing down the grace period. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu.c | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/urcu.c b/urcu.c index c421846..2d5c510 100644 --- a/urcu.c +++ b/urcu.c @@ -215,33 +215,16 @@ static void wait_gp(void) NULL, NULL, 0); } -static void update_counter_and_wait(void) +static void wait_for_readers(void) { CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; - /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); - - /* - * Must commit rcu_gp_ctr update to memory before waiting for quiescent - * state. Failure to do so could result in the writer waiting forever - * while new readers are always accessing data (no progress). Enforce - * compiler-order of store to rcu_gp_ctr before load rcu_reader ctr. - */ - cmm_barrier(); - - /* - * - * Adding a cmm_smp_mb() which is _not_ formally required, but makes the - * model easier to understand. It does not have a big performance impact - * anyway, given this is the write-side. - */ - cmm_smp_mb(); - /* - * Wait for each thread URCU_TLS(rcu_reader).ctr count to become 0. + * Wait for each thread URCU_TLS(rcu_reader).ctr to either + * indicate quiescence (not nested), or observe the current + * rcu_gp_ctr value. */ for (;;) { wait_loops++; @@ -316,12 +299,12 @@ void synchronize_rcu(void) smp_mb_master(RCU_MB_GROUP); /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe original parity or be quiescent. */ - update_counter_and_wait(); /* 0 -> 1, wait readers in parity 0 */ + wait_for_readers(); /* - * Must finish waiting for quiescent state for parity 0 before + * Must finish waiting for quiescent state for original parity before * committing next rcu_gp_ctr update to memory. Failure to do so could * result in the writer waiting forever while new readers are always * accessing data (no progress). Enforce compiler-order of load @@ -336,10 +319,29 @@ void synchronize_rcu(void) */ cmm_smp_mb(); + /* Switch parity: 0 -> 1, 1 -> 0 */ + CMM_STORE_SHARED(rcu_gp_ctr, rcu_gp_ctr ^ RCU_GP_CTR_PHASE); + + /* + * Must commit rcu_gp_ctr update to memory before waiting for quiescent + * state. Failure to do so could result in the writer waiting forever + * while new readers are always accessing data (no progress). Enforce + * compiler-order of store to rcu_gp_ctr before load rcu_reader ctr. + */ + cmm_barrier(); + + /* + * + * Adding a cmm_smp_mb() which is _not_ formally required, but makes the + * model easier to understand. It does not have a big performance impact + * anyway, given this is the write-side. + */ + cmm_smp_mb(); + /* - * Wait for previous parity to be empty of readers. + * Wait for readers to observe new parity or be quiescent. */ - update_counter_and_wait(); /* 1 -> 0, wait readers in parity 1 */ + wait_for_readers(); /* Finish waiting for reader threads before letting the old ptr being * freed. Must be done within rcu_gp_lock because it iterates on reader -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:25 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:25 -0500 Subject: [lttng-dev] [PATCH 12/16] urcu-bp: move quiescent threads to separate list In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-13-git-send-email-mathieu.desnoyers@efficios.com> Accelerate 2-phase grace period by not having to iterate twice on threads not within RCU read-side critical section. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-bp.c | 46 +++++++++++++++++++++++++++++++++++----------- urcu/static/urcu-bp.h | 29 +++++++++++++++++++---------- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/urcu-bp.c b/urcu-bp.c index 4b3cf01..f99c0e5 100644 --- a/urcu-bp.c +++ b/urcu-bp.c @@ -115,7 +115,7 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); * Also has a RCU_GP_COUNT of 1, to accelerate the reader fast path. * Written to only by writer with mutex taken. Read by both writer and readers. */ -long rcu_gp_ctr = RCU_GP_COUNT; +unsigned long rcu_gp_ctr = RCU_GP_COUNT; /* * Pointer to registry elements. Written to only by each individual reader. Read @@ -164,9 +164,10 @@ static void mutex_unlock(pthread_mutex_t *mutex) urcu_die(ret); } -static void wait_for_readers(void) +static void wait_for_readers(struct cds_list_head *input_readers, + struct cds_list_head *cur_snap_readers, + struct cds_list_head *qsreaders) { - CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; @@ -177,12 +178,30 @@ static void wait_for_readers(void) */ for (;;) { wait_loops++; - cds_list_for_each_entry_safe(index, tmp, ®istry, node) { - if (!rcu_old_gp_ongoing(&index->ctr)) - cds_list_move(&index->node, &qsreaders); + cds_list_for_each_entry_safe(index, tmp, input_readers, node) { + switch (rcu_reader_state(&index->ctr)) { + case RCU_READER_ACTIVE_CURRENT: + if (cur_snap_readers) { + cds_list_move(&index->node, + cur_snap_readers); + break; + } + /* Fall-through */ + case RCU_READER_INACTIVE: + cds_list_move(&index->node, qsreaders); + break; + case RCU_READER_ACTIVE_OLD: + /* + * Old snapshot. Leaving node in + * input_readers will make us busy-loop + * until the snapshot becomes current or + * the reader becomes inactive. + */ + break; + } } - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { break; } else { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) @@ -191,12 +210,12 @@ static void wait_for_readers(void) caa_cpu_relax(); } } - /* put back the reader list in the registry */ - cds_list_splice(&qsreaders, ®istry); } void synchronize_rcu(void) { + CDS_LIST_HEAD(cur_snap_readers); + CDS_LIST_HEAD(qsreaders); sigset_t newmask, oldmask; int ret; @@ -221,7 +240,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe original parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders); /* * Adding a cmm_smp_mb() which is _not_ formally required, but makes the @@ -250,7 +269,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); /* * Finish waiting for reader threads before letting the old ptr being diff --git a/urcu/static/urcu-bp.h b/urcu/static/urcu-bp.h index c52a688..c7f5326 100644 --- a/urcu/static/urcu-bp.h +++ b/urcu/static/urcu-bp.h @@ -58,6 +58,12 @@ extern "C" { #define rcu_assert(args...) #endif +enum rcu_state { + RCU_READER_ACTIVE_CURRENT, + RCU_READER_ACTIVE_OLD, + RCU_READER_INACTIVE, +}; + #ifdef DEBUG_YIELD #include #include @@ -129,11 +135,11 @@ extern void rcu_bp_register(void); * Using a int rather than a char to eliminate false register dependencies * causing stalls on some architectures. */ -extern long rcu_gp_ctr; +extern unsigned long rcu_gp_ctr; struct rcu_reader { /* Data used by both reader and synchronize_rcu() */ - long ctr; + unsigned long ctr; /* Data used for registry */ struct cds_list_head node __attribute__((aligned(CAA_CACHE_LINE_SIZE))); pthread_t tid; @@ -147,19 +153,22 @@ struct rcu_reader { */ extern DECLARE_URCU_TLS(struct rcu_reader *, rcu_reader); -static inline int rcu_old_gp_ongoing(long *value) +static inline enum rcu_state rcu_reader_state(unsigned long *ctr) { - long v; + unsigned long v; - if (value == NULL) - return 0; + if (ctr == NULL) + return RCU_READER_INACTIVE; /* * Make sure both tests below are done on the same version of *value * to insure consistency. */ - v = CMM_LOAD_SHARED(*value); - return (v & RCU_GP_CTR_NEST_MASK) && - ((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE); + v = CMM_LOAD_SHARED(*ctr); + if (!(v & RCU_GP_CTR_NEST_MASK)) + return RCU_READER_INACTIVE; + if (!((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE)) + return RCU_READER_ACTIVE_CURRENT; + return RCU_READER_ACTIVE_OLD; } /* @@ -190,7 +199,7 @@ static inline void _rcu_read_lock_update(unsigned long tmp) */ static inline void _rcu_read_lock(void) { - long tmp; + unsigned long tmp; if (caa_unlikely(!URCU_TLS(rcu_reader))) rcu_bp_register(); /* If not yet registered. */ -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:24 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:24 -0500 Subject: [lttng-dev] [PATCH 11/16] urcu-mb/signal/membarrier: move quiescent threads to separate list In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-12-git-send-email-mathieu.desnoyers@efficios.com> Accelerate 2-phase grace period by not having to iterate twice on threads not nested within a RCU read-side lock. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu.c | 47 ++++++++++++++++++++++++++++++++++++----------- urcu/static/urcu.h | 15 ++++++++++++--- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/urcu.c b/urcu.c index 2d5c510..e6ff0f3 100644 --- a/urcu.c +++ b/urcu.c @@ -215,9 +215,10 @@ static void wait_gp(void) NULL, NULL, 0); } -static void wait_for_readers(void) +static void wait_for_readers(struct cds_list_head *input_readers, + struct cds_list_head *cur_snap_readers, + struct cds_list_head *qsreaders) { - CDS_LIST_HEAD(qsreaders); int wait_loops = 0; struct rcu_reader *index, *tmp; @@ -234,13 +235,31 @@ static void wait_for_readers(void) smp_mb_master(RCU_MB_GROUP); } - cds_list_for_each_entry_safe(index, tmp, ®istry, node) { - if (!rcu_gp_ongoing(&index->ctr)) - cds_list_move(&index->node, &qsreaders); + cds_list_for_each_entry_safe(index, tmp, input_readers, node) { + switch (rcu_reader_state(&index->ctr)) { + case RCU_READER_ACTIVE_CURRENT: + if (cur_snap_readers) { + cds_list_move(&index->node, + cur_snap_readers); + break; + } + /* Fall-through */ + case RCU_READER_INACTIVE: + cds_list_move(&index->node, qsreaders); + break; + case RCU_READER_ACTIVE_OLD: + /* + * Old snapshot. Leaving node in + * input_readers will make us busy-loop + * until the snapshot becomes current or + * the reader becomes inactive. + */ + break; + } } #ifndef HAS_INCOHERENT_CACHES - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { /* Read reader_gp before write futex */ smp_mb_master(RCU_MB_GROUP); @@ -259,7 +278,7 @@ static void wait_for_readers(void) * URCU_TLS(rcu_reader).ctr update to memory if we wait * for too long. */ - if (cds_list_empty(®istry)) { + if (cds_list_empty(input_readers)) { if (wait_loops == RCU_QS_ACTIVE_ATTEMPTS) { /* Read reader_gp before write futex */ smp_mb_master(RCU_MB_GROUP); @@ -281,12 +300,13 @@ static void wait_for_readers(void) } #endif /* #else #ifndef HAS_INCOHERENT_CACHES */ } - /* put back the reader list in the registry */ - cds_list_splice(&qsreaders, ®istry); } void synchronize_rcu(void) { + CDS_LIST_HEAD(cur_snap_readers); + CDS_LIST_HEAD(qsreaders); + mutex_lock(&rcu_gp_lock); if (cds_list_empty(®istry)) @@ -301,7 +321,7 @@ void synchronize_rcu(void) /* * Wait for readers to observe original parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders); /* * Must finish waiting for quiescent state for original parity before @@ -341,7 +361,12 @@ void synchronize_rcu(void) /* * Wait for readers to observe new parity or be quiescent. */ - wait_for_readers(); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders); + + /* + * Put quiescent reader list back into registry. + */ + cds_list_splice(&qsreaders, ®istry); /* Finish waiting for reader threads before letting the old ptr being * freed. Must be done within rcu_gp_lock because it iterates on reader diff --git a/urcu/static/urcu.h b/urcu/static/urcu.h index f32f300..973826a 100644 --- a/urcu/static/urcu.h +++ b/urcu/static/urcu.h @@ -96,6 +96,12 @@ extern "C" { #define SIGRCU SIGUSR1 #endif +enum rcu_state { + RCU_READER_ACTIVE_CURRENT, + RCU_READER_ACTIVE_OLD, + RCU_READER_INACTIVE, +}; + #ifdef DEBUG_RCU #define rcu_assert(args...) assert(args) #else @@ -239,7 +245,7 @@ static inline void wake_up_gp(void) } } -static inline int rcu_gp_ongoing(unsigned long *ctr) +static inline enum rcu_state rcu_reader_state(unsigned long *ctr) { unsigned long v; @@ -248,8 +254,11 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) * to insure consistency. */ v = CMM_LOAD_SHARED(*ctr); - return (v & RCU_GP_CTR_NEST_MASK) && - ((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE); + if (!(v & RCU_GP_CTR_NEST_MASK)) + return RCU_READER_INACTIVE; + if (!((v ^ rcu_gp_ctr) & RCU_GP_CTR_PHASE)) + return RCU_READER_ACTIVE_CURRENT; + return RCU_READER_ACTIVE_OLD; } /* -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:26 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:26 -0500 Subject: [lttng-dev] [PATCH 13/16] tests: use standard malloc/free for synchronize_rcu() In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-14-git-send-email-mathieu.desnoyers@efficios.com> Allows removing mutex from tests, which allow testing scalability of concurrent synchronize_rcu() executions. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- tests/test_urcu.c | 60 ++++++++--------------------------------------- tests/test_urcu_bp.c | 59 +++++++--------------------------------------- tests/test_urcu_qsbr.c | 61 ++++++++---------------------------------------- 3 files changed, 29 insertions(+), 151 deletions(-) diff --git a/tests/test_urcu.c b/tests/test_urcu.c index 6463d67..87972aa 100644 --- a/tests/test_urcu.c +++ b/tests/test_urcu.c @@ -66,15 +66,11 @@ static inline pid_t gettid(void) #endif #include -struct test_array { - int a; -}; - static volatile int test_go, test_stop; static unsigned long wdelay; -static struct test_array *test_rcu_pointer; +static int *test_rcu_pointer; static unsigned long duration; @@ -185,43 +181,10 @@ void rcu_copy_mutex_unlock(void) } } -/* - * malloc/free are reusing memory areas too quickly, which does not let us - * test races appropriately. Use a large circular array for allocations. - * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across - * both alloc and free, which insures we never run over our tail. - */ -#define ARRAY_SIZE (1048576 * nr_writers) -#define ARRAY_POISON 0xDEADBEEF -static int array_index; -static struct test_array *test_array; - -static struct test_array *test_array_alloc(void) -{ - struct test_array *ret; - int index; - - index = array_index % ARRAY_SIZE; - assert(test_array[index].a == ARRAY_POISON || - test_array[index].a == 0); - ret = &test_array[index]; - array_index++; - if (array_index == ARRAY_SIZE) - array_index = 0; - return ret; -} - -static void test_array_free(struct test_array *ptr) -{ - if (!ptr) - return; - ptr->a = ARRAY_POISON; -} - void *thr_reader(void *_count) { unsigned long long *count = _count; - struct test_array *local_ptr; + int *local_ptr; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), @@ -241,7 +204,7 @@ void *thr_reader(void *_count) local_ptr = rcu_dereference(test_rcu_pointer); rcu_debug_yield_read(); if (local_ptr) - assert(local_ptr->a == 8); + assert(*local_ptr == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); @@ -267,7 +230,7 @@ void *thr_reader(void *_count) void *thr_writer(void *_count) { unsigned long long *count = _count; - struct test_array *new, *old; + int *new, *old; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), @@ -281,17 +244,16 @@ void *thr_writer(void *_count) cmm_smp_mb(); for (;;) { - rcu_copy_mutex_lock(); - new = test_array_alloc(); - new->a = 8; + new = malloc(sizeof(int)); + assert(new); + *new = 8; old = rcu_xchg_pointer(&test_rcu_pointer, new); if (caa_unlikely(wduration)) loop_sleep(wduration); synchronize_rcu(); if (old) - old->a = 0; - test_array_free(old); - rcu_copy_mutex_unlock(); + *old = 0; + free(old); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; @@ -409,7 +371,6 @@ int main(int argc, char **argv) "main", (unsigned long) pthread_self(), (unsigned long)gettid()); - test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); @@ -459,8 +420,7 @@ int main(int argc, char **argv) argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); - test_array_free(test_rcu_pointer); - free(test_array); + free(test_rcu_pointer); free(tid_reader); free(tid_writer); free(count_reader); diff --git a/tests/test_urcu_bp.c b/tests/test_urcu_bp.c index 7902388..58afe90 100644 --- a/tests/test_urcu_bp.c +++ b/tests/test_urcu_bp.c @@ -66,15 +66,11 @@ static inline pid_t gettid(void) #endif #include -struct test_array { - int a; -}; - static volatile int test_go, test_stop; static unsigned long wdelay; -static struct test_array *test_rcu_pointer; +static int *test_rcu_pointer; static unsigned long duration; @@ -185,43 +181,10 @@ void rcu_copy_mutex_unlock(void) } } -/* - * malloc/free are reusing memory areas too quickly, which does not let us - * test races appropriately. Use a large circular array for allocations. - * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across - * both alloc and free, which insures we never run over our tail. - */ -#define ARRAY_SIZE (1048576 * nr_writers) -#define ARRAY_POISON 0xDEADBEEF -static int array_index; -static struct test_array *test_array; - -static struct test_array *test_array_alloc(void) -{ - struct test_array *ret; - int index; - - index = array_index % ARRAY_SIZE; - assert(test_array[index].a == ARRAY_POISON || - test_array[index].a == 0); - ret = &test_array[index]; - array_index++; - if (array_index == ARRAY_SIZE) - array_index = 0; - return ret; -} - -static void test_array_free(struct test_array *ptr) -{ - if (!ptr) - return; - ptr->a = ARRAY_POISON; -} - void *thr_reader(void *_count) { unsigned long long *count = _count; - struct test_array *local_ptr; + int *local_ptr; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), @@ -241,7 +204,7 @@ void *thr_reader(void *_count) local_ptr = rcu_dereference(test_rcu_pointer); rcu_debug_yield_read(); if (local_ptr) - assert(local_ptr->a == 8); + assert(*local_ptr == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); @@ -263,7 +226,7 @@ void *thr_reader(void *_count) void *thr_writer(void *_count) { unsigned long long *count = _count; - struct test_array *new, *old; + int *new, *old; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), @@ -277,17 +240,15 @@ void *thr_writer(void *_count) cmm_smp_mb(); for (;;) { - rcu_copy_mutex_lock(); - new = test_array_alloc(); - new->a = 8; + new = malloc(sizeof(int)); + *new = 8; old = rcu_xchg_pointer(&test_rcu_pointer, new); if (caa_unlikely(wduration)) loop_sleep(wduration); synchronize_rcu(); if (old) - old->a = 0; - test_array_free(old); - rcu_copy_mutex_unlock(); + *old = 0; + free(old); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; @@ -405,7 +366,6 @@ int main(int argc, char **argv) "main", (unsigned long) pthread_self(), (unsigned long) gettid()); - test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); @@ -455,8 +415,7 @@ int main(int argc, char **argv) argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); - test_array_free(test_rcu_pointer); - free(test_array); + free(test_rcu_pointer); free(tid_reader); free(tid_writer); free(count_reader); diff --git a/tests/test_urcu_qsbr.c b/tests/test_urcu_qsbr.c index da26b77..d5d893c 100644 --- a/tests/test_urcu_qsbr.c +++ b/tests/test_urcu_qsbr.c @@ -66,15 +66,11 @@ static inline pid_t gettid(void) #endif #include "urcu-qsbr.h" -struct test_array { - int a; -}; - static volatile int test_go, test_stop; static unsigned long wdelay; -static struct test_array *test_rcu_pointer; +static int *test_rcu_pointer; static unsigned long duration; @@ -184,43 +180,10 @@ void rcu_copy_mutex_unlock(void) } } -/* - * malloc/free are reusing memory areas too quickly, which does not let us - * test races appropriately. Use a large circular array for allocations. - * ARRAY_SIZE is larger than nr_writers, and we keep the mutex across - * both alloc and free, which insures we never run over our tail. - */ -#define ARRAY_SIZE (1048576 * nr_writers) -#define ARRAY_POISON 0xDEADBEEF -static int array_index; -static struct test_array *test_array; - -static struct test_array *test_array_alloc(void) -{ - struct test_array *ret; - int index; - - index = array_index % ARRAY_SIZE; - assert(test_array[index].a == ARRAY_POISON || - test_array[index].a == 0); - ret = &test_array[index]; - array_index++; - if (array_index == ARRAY_SIZE) - array_index = 0; - return ret; -} - -static void test_array_free(struct test_array *ptr) -{ - if (!ptr) - return; - ptr->a = ARRAY_POISON; -} - void *thr_reader(void *_count) { unsigned long long *count = _count; - struct test_array *local_ptr; + int *local_ptr; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "reader", (unsigned long) pthread_self(), @@ -240,7 +203,7 @@ void *thr_reader(void *_count) local_ptr = rcu_dereference(test_rcu_pointer); rcu_debug_yield_read(); if (local_ptr) - assert(local_ptr->a == 8); + assert(*local_ptr == 8); if (caa_unlikely(rduration)) loop_sleep(rduration); rcu_read_unlock(); @@ -269,7 +232,7 @@ void *thr_reader(void *_count) void *thr_writer(void *_count) { unsigned long long *count = _count; - struct test_array *new, *old; + int *new, *old; printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n", "writer", (unsigned long) pthread_self(), @@ -283,18 +246,16 @@ void *thr_writer(void *_count) cmm_smp_mb(); for (;;) { - rcu_copy_mutex_lock(); - new = test_array_alloc(); - new->a = 8; + new = malloc(sizeof(int)); + assert(new); + *new = 8; old = rcu_xchg_pointer(&test_rcu_pointer, new); if (caa_unlikely(wduration)) loop_sleep(wduration); synchronize_rcu(); - /* can be done after unlock */ if (old) - old->a = 0; - test_array_free(old); - rcu_copy_mutex_unlock(); + *old = 0; + free(old); URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; @@ -412,7 +373,6 @@ int main(int argc, char **argv) "main", (unsigned long) pthread_self(), (unsigned long) gettid()); - test_array = calloc(1, sizeof(*test_array) * ARRAY_SIZE); tid_reader = malloc(sizeof(*tid_reader) * nr_readers); tid_writer = malloc(sizeof(*tid_writer) * nr_writers); count_reader = malloc(sizeof(*count_reader) * nr_readers); @@ -462,8 +422,7 @@ int main(int argc, char **argv) argv[0], duration, nr_readers, rduration, wduration, nr_writers, wdelay, tot_reads, tot_writes, tot_reads + tot_writes); - test_array_free(test_rcu_pointer); - free(test_array); + free(test_rcu_pointer); free(tid_reader); free(tid_writer); free(count_reader); -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:27 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:27 -0500 Subject: [lttng-dev] [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> Here are benchmarks on batching of synchronize_rcu(), and it leads to very interesting scalability improvement and speedups, e.g., on a 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater threads, each updater using synchronize_rcu()): * Serialized grace periods : ./test_urcu_qsbr 4 20 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 20251412728 nr_writes 1826331 nr_ops 20253239059 * Batched grace periods : ./test_urcu_qsbr 4 20 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 15141994746 nr_writes 9382515 nr_ops 15151377261 For a 9382515/1826331 = 5.13 speedup for 20 updaters. Of course, we can see that readers have slowed down, probably due to increased update traffic, given there is no change to the read-side code whatsoever. Now let's see the penality of managing the stack for single-updater. With 4 readers, single updater: * Serialized grace periods : ./test_urcu_qsbr 4 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 19240784755 nr_writes 2130839 nr_ops 19242915594 * Batched grace periods : ./test_urcu_qsbr 4 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 19160162768 nr_writes 2253068 nr_ops 1916241583 2253068 vs 2137036 -> a couple of runs show that this difference lost in the noise for single updater. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 5b341b5..7f747ed 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -36,6 +36,7 @@ #include #include "urcu/wfcqueue.h" +#include "urcu/wfstack.h" #include "urcu/map/urcu-qsbr.h" #define BUILD_QSBR_LIB #include "urcu/static/urcu-qsbr.h" @@ -78,6 +79,35 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); static CDS_LIST_HEAD(registry); +/* + * Number of busy-loop attempts before waiting on futex for grace period + * batching. + */ +#define RCU_AWAKE_ATTEMPTS 1000 + +enum adapt_wakeup_state { + /* AWAKE_WAITING is compared directly (futex compares it). */ + AWAKE_WAITING = 0, + /* non-zero are used as masks. */ + AWAKE_WAKEUP = (1 << 0), + AWAKE_AWAKENED = (1 << 1), + AWAKE_TEARDOWN = (1 << 2), +}; + +struct gp_waiters_thread { + struct cds_wfs_node node; + int32_t wait_futex; +}; + +/* + * Stack keeping threads awaiting to wait for a grace period. Contains + * struct gp_waiters_thread objects. + */ +static struct cds_wfs_stack gp_waiters = { + .head = CDS_WFS_END, + .lock = PTHREAD_MUTEX_INITIALIZER, +}; + static void mutex_lock(pthread_mutex_t *mutex) { int ret; @@ -116,6 +146,58 @@ static void wait_gp(void) NULL, NULL, 0); } +/* + * Note: urcu_adaptative_wake_up needs "value" to stay allocated + * throughout its execution. In this scheme, the waiter owns the futex + * memory, and we only allow it to free this memory when it receives the + * AWAKE_TEARDOWN flag. + */ +static void urcu_adaptative_wake_up(int32_t *value) +{ + cmm_smp_mb(); + assert(uatomic_read(value) == AWAKE_WAITING); + uatomic_set(value, AWAKE_WAKEUP); + if (!(uatomic_read(value) & AWAKE_AWAKENED)) + futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); + /* Allow teardown of "value" memory. */ + uatomic_or(value, AWAKE_TEARDOWN); +} + +/* + * Caller must initialize "value" to AWAKE_WAITING before passing its + * memory to waker thread. + */ +static void urcu_adaptative_busy_wait(int32_t *value) +{ + unsigned int i; + + /* Load and test condition before read futex */ + cmm_smp_rmb(); + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { + if (uatomic_read(value) != AWAKE_WAITING) + goto skip_futex_wait; + caa_cpu_relax(); + } + futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); +skip_futex_wait: + + /* Tell waker thread than we are awakened. */ + uatomic_or(value, AWAKE_AWAKENED); + + /* + * Wait until waker thread lets us know it's ok to tear down + * memory allocated for value. + */ + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { + if (uatomic_read(value) & AWAKE_TEARDOWN) + break; + caa_cpu_relax(); + } + while (!(uatomic_read(value) & AWAKE_TEARDOWN)) + poll(NULL, 0, 10); + assert(uatomic_read(value) & AWAKE_TEARDOWN); +} + static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, struct cds_list_head *qsreaders) @@ -198,6 +280,9 @@ void synchronize_rcu(void) CDS_LIST_HEAD(cur_snap_readers); CDS_LIST_HEAD(qsreaders); unsigned long was_online; + struct gp_waiters_thread gp_waiters_thread; + struct cds_wfs_head *gp_waiters_head; + struct cds_wfs_node *waiters_iter, *waiters_iter_n; was_online = URCU_TLS(rcu_reader).ctr; @@ -214,8 +299,26 @@ void synchronize_rcu(void) else cmm_smp_mb(); + /* + * Add ourself to gp_waiters stack of threads awaiting to wait + * for a grace period. Proceed to perform the grace period only + * if we are the first thread added into the stack. + */ + cds_wfs_node_init(&gp_waiters_thread.node); + gp_waiters_thread.wait_futex = AWAKE_WAITING; + if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { + /* Not first in stack: will be awakened by another thread. */ + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); + goto gp_end; + } + mutex_lock(&rcu_gp_lock); + /* + * Pop all waiters into our local stack head. + */ + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); + if (cds_list_empty(®istry)) goto out; @@ -272,6 +375,19 @@ void synchronize_rcu(void) out: mutex_unlock(&rcu_gp_lock); + /* Wake all waiters in our stack head, excluding ourself. */ + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, + waiters_iter_n) { + struct gp_waiters_thread *wt; + + wt = caa_container_of(waiters_iter, + struct gp_waiters_thread, node); + if (wt == &gp_waiters_thread) + continue; + urcu_adaptative_wake_up(&wt->wait_futex); + } + +gp_end: /* * Finish waiting for reader threads before letting the old ptr being * freed. @@ -286,6 +402,9 @@ void synchronize_rcu(void) { CDS_LIST_HEAD(qsreaders); unsigned long was_online; + struct gp_waiters_thread gp_waiters_thread; + struct cds_wfs_head *gp_waiters_head; + struct cds_wfs_node *waiters_iter, *waiters_iter_n; was_online = URCU_TLS(rcu_reader).ctr; @@ -299,7 +418,26 @@ void synchronize_rcu(void) else cmm_smp_mb(); + /* + * Add ourself to gp_waiters stack of threads awaiting to wait + * for a grace period. Proceed to perform the grace period only + * if we are the first thread added into the stack. + */ + cds_wfs_node_init(&gp_waiters_thread.node); + gp_waiters_thread.wait_futex = AWAKE_WAITING; + if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { + /* Not first in stack: will be awakened by another thread. */ + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); + goto gp_end; + } + mutex_lock(&rcu_gp_lock); + + /* + * Pop all waiters into our local stack head. + */ + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); + if (cds_list_empty(®istry)) goto out; @@ -334,6 +472,19 @@ void synchronize_rcu(void) out: mutex_unlock(&rcu_gp_lock); + /* Wake all waiters in our stack head, excluding ourself. */ + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, + waiters_iter_n) { + struct gp_waiters_thread *wt; + + wt = caa_container_of(waiters_iter, + struct gp_waiters_thread, node); + if (wt == &gp_waiters_thread) + continue; + urcu_adaptative_wake_up(&wt->wait_futex); + } + +gp_end: if (was_online) rcu_thread_online(); else -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:28 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:28 -0500 Subject: [lttng-dev] [PATCH 15/16] urcu-wait: move wait code into separate file In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-16-git-send-email-mathieu.desnoyers@efficios.com> Signed-off-by: Mathieu Desnoyers --- Makefile.am | 2 +- urcu-qsbr.c | 82 +++++---------------------------------------- urcu-wait.h | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 75 deletions(-) create mode 100644 urcu-wait.h diff --git a/Makefile.am b/Makefile.am index 195b89a..0a4d357 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,7 @@ nobase_dist_include_HEADERS = urcu/compiler.h urcu/hlist.h urcu/list.h \ urcu/tls-compat.h nobase_nodist_include_HEADERS = urcu/arch.h urcu/uatomic.h urcu/config.h -dist_noinst_HEADERS = urcu-die.h +dist_noinst_HEADERS = urcu-die.h urcu-wait.h EXTRA_DIST = $(top_srcdir)/urcu/arch/*.h $(top_srcdir)/urcu/uatomic/*.h \ gpl-2.0.txt lgpl-2.1.txt lgpl-relicensing.txt \ diff --git a/urcu-qsbr.c b/urcu-qsbr.c index 7f747ed..d691389 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -44,6 +44,7 @@ #include "urcu/tls-compat.h" #include "urcu-die.h" +#include "urcu-wait.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE @@ -79,24 +80,9 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); static CDS_LIST_HEAD(registry); -/* - * Number of busy-loop attempts before waiting on futex for grace period - * batching. - */ -#define RCU_AWAKE_ATTEMPTS 1000 - -enum adapt_wakeup_state { - /* AWAKE_WAITING is compared directly (futex compares it). */ - AWAKE_WAITING = 0, - /* non-zero are used as masks. */ - AWAKE_WAKEUP = (1 << 0), - AWAKE_AWAKENED = (1 << 1), - AWAKE_TEARDOWN = (1 << 2), -}; - struct gp_waiters_thread { struct cds_wfs_node node; - int32_t wait_futex; + struct urcu_wait wait; }; /* @@ -146,58 +132,6 @@ static void wait_gp(void) NULL, NULL, 0); } -/* - * Note: urcu_adaptative_wake_up needs "value" to stay allocated - * throughout its execution. In this scheme, the waiter owns the futex - * memory, and we only allow it to free this memory when it receives the - * AWAKE_TEARDOWN flag. - */ -static void urcu_adaptative_wake_up(int32_t *value) -{ - cmm_smp_mb(); - assert(uatomic_read(value) == AWAKE_WAITING); - uatomic_set(value, AWAKE_WAKEUP); - if (!(uatomic_read(value) & AWAKE_AWAKENED)) - futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); - /* Allow teardown of "value" memory. */ - uatomic_or(value, AWAKE_TEARDOWN); -} - -/* - * Caller must initialize "value" to AWAKE_WAITING before passing its - * memory to waker thread. - */ -static void urcu_adaptative_busy_wait(int32_t *value) -{ - unsigned int i; - - /* Load and test condition before read futex */ - cmm_smp_rmb(); - for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { - if (uatomic_read(value) != AWAKE_WAITING) - goto skip_futex_wait; - caa_cpu_relax(); - } - futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); -skip_futex_wait: - - /* Tell waker thread than we are awakened. */ - uatomic_or(value, AWAKE_AWAKENED); - - /* - * Wait until waker thread lets us know it's ok to tear down - * memory allocated for value. - */ - for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { - if (uatomic_read(value) & AWAKE_TEARDOWN) - break; - caa_cpu_relax(); - } - while (!(uatomic_read(value) & AWAKE_TEARDOWN)) - poll(NULL, 0, 10); - assert(uatomic_read(value) & AWAKE_TEARDOWN); -} - static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, struct cds_list_head *qsreaders) @@ -305,10 +239,10 @@ void synchronize_rcu(void) * if we are the first thread added into the stack. */ cds_wfs_node_init(&gp_waiters_thread.node); - gp_waiters_thread.wait_futex = AWAKE_WAITING; + urcu_wait_init(&gp_waiters_thread.wait); if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { /* Not first in stack: will be awakened by another thread. */ - urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); + urcu_adaptative_busy_wait(&gp_waiters_thread.wait); goto gp_end; } @@ -384,7 +318,7 @@ out: struct gp_waiters_thread, node); if (wt == &gp_waiters_thread) continue; - urcu_adaptative_wake_up(&wt->wait_futex); + urcu_adaptative_wake_up(&wt->wait); } gp_end: @@ -424,10 +358,10 @@ void synchronize_rcu(void) * if we are the first thread added into the stack. */ cds_wfs_node_init(&gp_waiters_thread.node); - gp_waiters_thread.wait_futex = AWAKE_WAITING; + urcu_wait_init(&gp_waiters_thread.wait); if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { /* Not first in stack: will be awakened by another thread. */ - urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); + urcu_adaptative_busy_wait(&gp_waiters_thread.wait); goto gp_end; } @@ -481,7 +415,7 @@ out: struct gp_waiters_thread, node); if (wt == &gp_waiters_thread) continue; - urcu_adaptative_wake_up(&wt->wait_futex); + urcu_adaptative_wake_up(&wt->wait); } gp_end: diff --git a/urcu-wait.h b/urcu-wait.h new file mode 100644 index 0000000..13f26cc --- /dev/null +++ b/urcu-wait.h @@ -0,0 +1,107 @@ +#ifndef _URCU_WAIT_H +#define _URCU_WAIT_H + +/* + * urcu-wait.h + * + * Userspace RCU library wait/wakeup management + * + * Copyright (c) 2012 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * Number of busy-loop attempts before waiting on futex for grace period + * batching. + */ +#define URCU_WAIT_ATTEMPTS 1000 + +enum urcu_wait_state { + /* URCU_WAIT_WAITING is compared directly (futex compares it). */ + URCU_WAIT_WAITING = 0, + /* non-zero are used as masks. */ + URCU_WAIT_WAKEUP = (1 << 0), + URCU_WAIT_AWAKENED = (1 << 1), + URCU_WAIT_TEARDOWN = (1 << 2), +}; + +struct urcu_wait { + int32_t futex; +}; + +static inline +void urcu_wait_init(struct urcu_wait *wait) +{ + wait->futex = URCU_WAIT_WAITING; +} + +/* + * Note: urcu_adaptative_wake_up needs "value" to stay allocated + * throughout its execution. In this scheme, the waiter owns the futex + * memory, and we only allow it to free this memory when it receives the + * URCU_WAIT_TEARDOWN flag. + */ +static inline +void urcu_adaptative_wake_up(struct urcu_wait *wait) +{ + cmm_smp_mb(); + assert(uatomic_read(&wait->futex) == URCU_WAIT_WAITING); + uatomic_set(&wait->futex, URCU_WAIT_WAKEUP); + if (!(uatomic_read(&wait->futex) & URCU_WAIT_AWAKENED)) + futex_noasync(&wait->futex, FUTEX_WAKE, 1, NULL, NULL, 0); + /* Allow teardown of struct urcu_wait memory. */ + uatomic_or(&wait->futex, URCU_WAIT_TEARDOWN); +} + +/* + * Caller must initialize "value" to URCU_WAIT_WAITING before passing its + * memory to waker thread. + */ +static void urcu_adaptative_busy_wait(struct urcu_wait *wait) +{ + unsigned int i; + + /* Load and test condition before read futex */ + cmm_smp_rmb(); + for (i = 0; i < URCU_WAIT_ATTEMPTS; i++) { + if (uatomic_read(&wait->futex) != URCU_WAIT_WAITING) + goto skip_futex_wait; + caa_cpu_relax(); + } + futex_noasync(&wait->futex, FUTEX_WAIT, + URCU_WAIT_WAITING, NULL, NULL, 0); +skip_futex_wait: + + /* Tell waker thread than we are awakened. */ + uatomic_or(&wait->futex, URCU_WAIT_AWAKENED); + + /* + * Wait until waker thread lets us know it's ok to tear down + * memory allocated for struct urcu_wait. + */ + for (i = 0; i < URCU_WAIT_ATTEMPTS; i++) { + if (uatomic_read(&wait->futex) & URCU_WAIT_TEARDOWN) + break; + caa_cpu_relax(); + } + while (!(uatomic_read(&wait->futex) & URCU_WAIT_TEARDOWN)) + poll(NULL, 0, 10); + assert(uatomic_read(&wait->futex) & URCU_WAIT_TEARDOWN); +} + +#endif /* _URCU_WAIT_H */ -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 20 14:40:29 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 20 Nov 2012 14:40:29 -0500 Subject: [lttng-dev] [PATCH 16/16] urcu-wait: move queue management code into urcu-wait.h In-Reply-To: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <1353440429-19223-17-git-send-email-mathieu.desnoyers@efficios.com> Note: urcu-wait.h is not yet exposed outside of userspace RCU. Signed-off-by: Mathieu Desnoyers --- urcu-qsbr.c | 72 ++++++++++-------------------------- urcu-wait.h | 119 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 117 insertions(+), 74 deletions(-) diff --git a/urcu-qsbr.c b/urcu-qsbr.c index d691389..9ae17de 100644 --- a/urcu-qsbr.c +++ b/urcu-qsbr.c @@ -80,19 +80,11 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); static CDS_LIST_HEAD(registry); -struct gp_waiters_thread { - struct cds_wfs_node node; - struct urcu_wait wait; -}; - /* * Stack keeping threads awaiting to wait for a grace period. Contains * struct gp_waiters_thread objects. */ -static struct cds_wfs_stack gp_waiters = { - .head = CDS_WFS_END, - .lock = PTHREAD_MUTEX_INITIALIZER, -}; +static DEFINE_URCU_WAIT_QUEUE(gp_waiters); static void mutex_lock(pthread_mutex_t *mutex) { @@ -214,9 +206,8 @@ void synchronize_rcu(void) CDS_LIST_HEAD(cur_snap_readers); CDS_LIST_HEAD(qsreaders); unsigned long was_online; - struct gp_waiters_thread gp_waiters_thread; - struct cds_wfs_head *gp_waiters_head; - struct cds_wfs_node *waiters_iter, *waiters_iter_n; + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); + struct urcu_waiters waiters; was_online = URCU_TLS(rcu_reader).ctr; @@ -238,20 +229,20 @@ void synchronize_rcu(void) * for a grace period. Proceed to perform the grace period only * if we are the first thread added into the stack. */ - cds_wfs_node_init(&gp_waiters_thread.node); - urcu_wait_init(&gp_waiters_thread.wait); - if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { + if (urcu_wait_add(&gp_waiters, &wait) != 0) { /* Not first in stack: will be awakened by another thread. */ - urcu_adaptative_busy_wait(&gp_waiters_thread.wait); + urcu_adaptative_busy_wait(&wait); goto gp_end; } + /* We won't need to wake ourself up */ + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); mutex_lock(&rcu_gp_lock); /* - * Pop all waiters into our local stack head. + * Move all waiters into our local queue. */ - gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); + urcu_move_waiters(&waiters, &gp_waiters); if (cds_list_empty(®istry)) goto out; @@ -308,19 +299,7 @@ void synchronize_rcu(void) cds_list_splice(&qsreaders, ®istry); out: mutex_unlock(&rcu_gp_lock); - - /* Wake all waiters in our stack head, excluding ourself. */ - cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, - waiters_iter_n) { - struct gp_waiters_thread *wt; - - wt = caa_container_of(waiters_iter, - struct gp_waiters_thread, node); - if (wt == &gp_waiters_thread) - continue; - urcu_adaptative_wake_up(&wt->wait); - } - + urcu_wake_all_waiters(&waiters); gp_end: /* * Finish waiting for reader threads before letting the old ptr being @@ -336,9 +315,8 @@ void synchronize_rcu(void) { CDS_LIST_HEAD(qsreaders); unsigned long was_online; - struct gp_waiters_thread gp_waiters_thread; - struct cds_wfs_head *gp_waiters_head; - struct cds_wfs_node *waiters_iter, *waiters_iter_n; + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); + struct urcu_waiters waiters; was_online = URCU_TLS(rcu_reader).ctr; @@ -357,20 +335,20 @@ void synchronize_rcu(void) * for a grace period. Proceed to perform the grace period only * if we are the first thread added into the stack. */ - cds_wfs_node_init(&gp_waiters_thread.node); - urcu_wait_init(&gp_waiters_thread.wait); - if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { + if (urcu_wait_add(&gp_waiters, &wait) != 0) { /* Not first in stack: will be awakened by another thread. */ - urcu_adaptative_busy_wait(&gp_waiters_thread.wait); + urcu_adaptative_busy_wait(&wait); goto gp_end; } + /* We won't need to wake ourself up */ + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); mutex_lock(&rcu_gp_lock); /* - * Pop all waiters into our local stack head. + * Move all waiters into our local queue. */ - gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); + urcu_move_waiters(&waiters, &gp_waiters); if (cds_list_empty(®istry)) goto out; @@ -405,19 +383,7 @@ void synchronize_rcu(void) cds_list_splice(&qsreaders, ®istry); out: mutex_unlock(&rcu_gp_lock); - - /* Wake all waiters in our stack head, excluding ourself. */ - cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, - waiters_iter_n) { - struct gp_waiters_thread *wt; - - wt = caa_container_of(waiters_iter, - struct gp_waiters_thread, node); - if (wt == &gp_waiters_thread) - continue; - urcu_adaptative_wake_up(&wt->wait); - } - + urcu_wake_all_waiters(&waiters); gp_end: if (was_online) rcu_thread_online(); diff --git a/urcu-wait.h b/urcu-wait.h index 13f26cc..e365b7c 100644 --- a/urcu-wait.h +++ b/urcu-wait.h @@ -24,6 +24,7 @@ */ #include +#include /* * Number of busy-loop attempts before waiting on futex for grace period @@ -36,72 +37,148 @@ enum urcu_wait_state { URCU_WAIT_WAITING = 0, /* non-zero are used as masks. */ URCU_WAIT_WAKEUP = (1 << 0), - URCU_WAIT_AWAKENED = (1 << 1), + URCU_WAIT_RUNNING = (1 << 1), URCU_WAIT_TEARDOWN = (1 << 2), }; -struct urcu_wait { - int32_t futex; +struct urcu_wait_node { + struct cds_wfs_node node; + int32_t state; /* enum urcu_wait_state */ }; +#define URCU_WAIT_NODE_INIT(name, _state) \ + { .state = _state } + +#define DEFINE_URCU_WAIT_NODE(name, state) \ + struct urcu_wait_node name = URCU_WAIT_NODE_INIT(name, state) + +#define DECLARE_URCU_WAIT_NODE(name) \ + struct urcu_wait_node name + +struct urcu_wait_queue { + struct cds_wfs_stack stack; +}; + +#define URCU_WAIT_QUEUE_HEAD_INIT(name) \ + { .stack.head = CDS_WFS_END, .stack.lock = PTHREAD_MUTEX_INITIALIZER } + +#define DECLARE_URCU_WAIT_QUEUE(name) \ + struct urcu_wait_queue name + +#define DEFINE_URCU_WAIT_QUEUE(name) \ + struct urcu_wait_queue name = URCU_WAIT_QUEUE_HEAD_INIT(name) + +struct urcu_waiters { + struct cds_wfs_head *head; +}; + +/* + * Add ourself atomically to a wait queue. Return 0 if queue was + * previously empty, else return 1. + */ +static inline +bool urcu_wait_add(struct urcu_wait_queue *queue, + struct urcu_wait_node *node) +{ + return cds_wfs_push(&queue->stack, &node->node); +} + +/* + * Atomically move all waiters from wait queue into our local struct + * urcu_waiters. + */ +static inline +void urcu_move_waiters(struct urcu_waiters *waiters, + struct urcu_wait_queue *queue) +{ + waiters->head = __cds_wfs_pop_all(&queue->stack); +} + +static inline +void urcu_wait_set_state(struct urcu_wait_node *node, + enum urcu_wait_state state) +{ + node->state = state; +} + static inline -void urcu_wait_init(struct urcu_wait *wait) +void urcu_wait_node_init(struct urcu_wait_node *node, + enum urcu_wait_state state) { - wait->futex = URCU_WAIT_WAITING; + urcu_wait_set_state(node, state); + cds_wfs_node_init(&node->node); } /* * Note: urcu_adaptative_wake_up needs "value" to stay allocated - * throughout its execution. In this scheme, the waiter owns the futex + * throughout its execution. In this scheme, the waiter owns the node * memory, and we only allow it to free this memory when it receives the * URCU_WAIT_TEARDOWN flag. */ static inline -void urcu_adaptative_wake_up(struct urcu_wait *wait) +void urcu_adaptative_wake_up(struct urcu_wait_node *wait) { cmm_smp_mb(); - assert(uatomic_read(&wait->futex) == URCU_WAIT_WAITING); - uatomic_set(&wait->futex, URCU_WAIT_WAKEUP); - if (!(uatomic_read(&wait->futex) & URCU_WAIT_AWAKENED)) - futex_noasync(&wait->futex, FUTEX_WAKE, 1, NULL, NULL, 0); + assert(uatomic_read(&wait->state) == URCU_WAIT_WAITING); + uatomic_set(&wait->state, URCU_WAIT_WAKEUP); + if (!(uatomic_read(&wait->state) & URCU_WAIT_RUNNING)) + futex_noasync(&wait->state, FUTEX_WAKE, 1, NULL, NULL, 0); /* Allow teardown of struct urcu_wait memory. */ - uatomic_or(&wait->futex, URCU_WAIT_TEARDOWN); + uatomic_or(&wait->state, URCU_WAIT_TEARDOWN); } /* * Caller must initialize "value" to URCU_WAIT_WAITING before passing its * memory to waker thread. */ -static void urcu_adaptative_busy_wait(struct urcu_wait *wait) +static inline +void urcu_adaptative_busy_wait(struct urcu_wait_node *wait) { unsigned int i; - /* Load and test condition before read futex */ + /* Load and test condition before read state */ cmm_smp_rmb(); for (i = 0; i < URCU_WAIT_ATTEMPTS; i++) { - if (uatomic_read(&wait->futex) != URCU_WAIT_WAITING) + if (uatomic_read(&wait->state) != URCU_WAIT_WAITING) goto skip_futex_wait; caa_cpu_relax(); } - futex_noasync(&wait->futex, FUTEX_WAIT, + futex_noasync(&wait->state, FUTEX_WAIT, URCU_WAIT_WAITING, NULL, NULL, 0); skip_futex_wait: - /* Tell waker thread than we are awakened. */ - uatomic_or(&wait->futex, URCU_WAIT_AWAKENED); + /* Tell waker thread than we are runnning. */ + uatomic_or(&wait->state, URCU_WAIT_RUNNING); /* * Wait until waker thread lets us know it's ok to tear down * memory allocated for struct urcu_wait. */ for (i = 0; i < URCU_WAIT_ATTEMPTS; i++) { - if (uatomic_read(&wait->futex) & URCU_WAIT_TEARDOWN) + if (uatomic_read(&wait->state) & URCU_WAIT_TEARDOWN) break; caa_cpu_relax(); } - while (!(uatomic_read(&wait->futex) & URCU_WAIT_TEARDOWN)) + while (!(uatomic_read(&wait->state) & URCU_WAIT_TEARDOWN)) poll(NULL, 0, 10); - assert(uatomic_read(&wait->futex) & URCU_WAIT_TEARDOWN); + assert(uatomic_read(&wait->state) & URCU_WAIT_TEARDOWN); +} + +static inline +void urcu_wake_all_waiters(struct urcu_waiters *waiters) +{ + struct cds_wfs_node *iter, *iter_n; + + /* Wake all waiters in our stack head */ + cds_wfs_for_each_blocking_safe(waiters->head, iter, iter_n) { + struct urcu_wait_node *wait_node = + caa_container_of(iter, struct urcu_wait_node, node); + + /* Don't wake already running threads */ + if (wait_node->state & URCU_WAIT_RUNNING) + continue; + urcu_adaptative_wake_up(wait_node); + } } #endif /* _URCU_WAIT_H */ -- 1.7.10.4 From laijs at cn.fujitsu.com Wed Nov 21 03:07:54 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Wed, 21 Nov 2012 16:07:54 +0800 Subject: [lttng-dev] [PATCH 01/16] Fix: wfcqueue nonblocking dequeue In-Reply-To: <1353440429-19223-2-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-2-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <50AC8BDA.9080309@cn.fujitsu.com> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > Failures were not handled in the nonblocking dequeue implementation. > > Signed-off-by: Mathieu Desnoyers > --- > urcu/static/wfcqueue.h | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > index 8733771..a284b58 100644 > --- a/urcu/static/wfcqueue.h > +++ b/urcu/static/wfcqueue.h > @@ -312,6 +312,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > return NULL; > > node = ___cds_wfcq_node_sync_next(&head->node, blocking); > + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) > + return CDS_WFCQ_WOULDBLOCK; > > if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { > /* > @@ -332,6 +334,15 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) > return node; Is it this simpler? we had just loaded node->next via "if ((next = CMM_LOAD_SHARED(node->next)) == NULL)" + if (!blocking) + return CDS_WFCQ_WOULDBLOCK > next = ___cds_wfcq_node_sync_next(node, blocking); and remove the following. > + /* > + * In nonblocking mode, if we would need to block to > + * get node's next, set the head next node pointer > + * (currently NULL) back to its original value. > + */ > + if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { > + head->node.next = node; > + return CDS_WFCQ_WOULDBLOCK; > + } > } > > /* From laijs at cn.fujitsu.com Wed Nov 21 03:22:46 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Wed, 21 Nov 2012 16:22:46 +0800 Subject: [lttng-dev] [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <50AC8F56.6040109@cn.fujitsu.com> Could you delay 14~16 for 40 days if I don't implement it in 40 days? On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > Here are benchmarks on batching of synchronize_rcu(), and it leads to > very interesting scalability improvement and speedups, e.g., on a > 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > threads, each updater using synchronize_rcu()): > > * Serialized grace periods : > > ./test_urcu_qsbr 4 20 20 > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 20251412728 nr_writes 1826331 nr_ops 20253239059 > > * Batched grace periods : > > ./test_urcu_qsbr 4 20 20 > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 15141994746 nr_writes 9382515 nr_ops 15151377261 > > For a 9382515/1826331 = 5.13 speedup for 20 updaters. > > Of course, we can see that readers have slowed down, probably due to > increased update traffic, given there is no change to the read-side code > whatsoever. > > Now let's see the penality of managing the stack for single-updater. > With 4 readers, single updater: > > * Serialized grace periods : > > ./test_urcu_qsbr 4 1 20 > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 19240784755 nr_writes 2130839 nr_ops 19242915594 > > * Batched grace periods : > > ./test_urcu_qsbr 4 1 20 > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 19160162768 nr_writes 2253068 nr_ops 1916241583 > > 2253068 vs 2137036 -> a couple of runs show that this difference lost in > the noise for single updater. > > CC: Paul E. McKenney > CC: Lai Jiangshan > CC: Alan Stern > Signed-off-by: Mathieu Desnoyers > --- > urcu-qsbr.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 151 insertions(+) > > diff --git a/urcu-qsbr.c b/urcu-qsbr.c > index 5b341b5..7f747ed 100644 > --- a/urcu-qsbr.c > +++ b/urcu-qsbr.c > @@ -36,6 +36,7 @@ > #include > > #include "urcu/wfcqueue.h" > +#include "urcu/wfstack.h" > #include "urcu/map/urcu-qsbr.h" > #define BUILD_QSBR_LIB > #include "urcu/static/urcu-qsbr.h" > @@ -78,6 +79,35 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > > static CDS_LIST_HEAD(registry); > > +/* > + * Number of busy-loop attempts before waiting on futex for grace period > + * batching. > + */ > +#define RCU_AWAKE_ATTEMPTS 1000 > + > +enum adapt_wakeup_state { > + /* AWAKE_WAITING is compared directly (futex compares it). */ > + AWAKE_WAITING = 0, > + /* non-zero are used as masks. */ > + AWAKE_WAKEUP = (1 << 0), > + AWAKE_AWAKENED = (1 << 1), > + AWAKE_TEARDOWN = (1 << 2), > +}; > + > +struct gp_waiters_thread { > + struct cds_wfs_node node; > + int32_t wait_futex; > +}; > + > +/* > + * Stack keeping threads awaiting to wait for a grace period. Contains > + * struct gp_waiters_thread objects. > + */ > +static struct cds_wfs_stack gp_waiters = { > + .head = CDS_WFS_END, > + .lock = PTHREAD_MUTEX_INITIALIZER, > +}; > + > static void mutex_lock(pthread_mutex_t *mutex) > { > int ret; > @@ -116,6 +146,58 @@ static void wait_gp(void) > NULL, NULL, 0); > } > > +/* > + * Note: urcu_adaptative_wake_up needs "value" to stay allocated > + * throughout its execution. In this scheme, the waiter owns the futex > + * memory, and we only allow it to free this memory when it receives the > + * AWAKE_TEARDOWN flag. > + */ > +static void urcu_adaptative_wake_up(int32_t *value) > +{ > + cmm_smp_mb(); > + assert(uatomic_read(value) == AWAKE_WAITING); > + uatomic_set(value, AWAKE_WAKEUP); > + if (!(uatomic_read(value) & AWAKE_AWAKENED)) > + futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); > + /* Allow teardown of "value" memory. */ > + uatomic_or(value, AWAKE_TEARDOWN); > +} > + > +/* > + * Caller must initialize "value" to AWAKE_WAITING before passing its > + * memory to waker thread. > + */ > +static void urcu_adaptative_busy_wait(int32_t *value) > +{ > + unsigned int i; > + > + /* Load and test condition before read futex */ > + cmm_smp_rmb(); > + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { > + if (uatomic_read(value) != AWAKE_WAITING) > + goto skip_futex_wait; > + caa_cpu_relax(); > + } > + futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); > +skip_futex_wait: > + > + /* Tell waker thread than we are awakened. */ > + uatomic_or(value, AWAKE_AWAKENED); > + > + /* > + * Wait until waker thread lets us know it's ok to tear down > + * memory allocated for value. > + */ > + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { > + if (uatomic_read(value) & AWAKE_TEARDOWN) > + break; > + caa_cpu_relax(); > + } > + while (!(uatomic_read(value) & AWAKE_TEARDOWN)) > + poll(NULL, 0, 10); > + assert(uatomic_read(value) & AWAKE_TEARDOWN); > +} > + > static void wait_for_readers(struct cds_list_head *input_readers, > struct cds_list_head *cur_snap_readers, > struct cds_list_head *qsreaders) > @@ -198,6 +280,9 @@ void synchronize_rcu(void) > CDS_LIST_HEAD(cur_snap_readers); > CDS_LIST_HEAD(qsreaders); > unsigned long was_online; > + struct gp_waiters_thread gp_waiters_thread; > + struct cds_wfs_head *gp_waiters_head; > + struct cds_wfs_node *waiters_iter, *waiters_iter_n; > > was_online = URCU_TLS(rcu_reader).ctr; > > @@ -214,8 +299,26 @@ void synchronize_rcu(void) > else > cmm_smp_mb(); > > + /* > + * Add ourself to gp_waiters stack of threads awaiting to wait > + * for a grace period. Proceed to perform the grace period only > + * if we are the first thread added into the stack. > + */ > + cds_wfs_node_init(&gp_waiters_thread.node); > + gp_waiters_thread.wait_futex = AWAKE_WAITING; > + if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { > + /* Not first in stack: will be awakened by another thread. */ > + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); > + goto gp_end; > + } > + > mutex_lock(&rcu_gp_lock); > > + /* > + * Pop all waiters into our local stack head. > + */ > + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); > + > if (cds_list_empty(®istry)) > goto out; > > @@ -272,6 +375,19 @@ void synchronize_rcu(void) > out: > mutex_unlock(&rcu_gp_lock); > > + /* Wake all waiters in our stack head, excluding ourself. */ > + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, > + waiters_iter_n) { > + struct gp_waiters_thread *wt; > + > + wt = caa_container_of(waiters_iter, > + struct gp_waiters_thread, node); > + if (wt == &gp_waiters_thread) > + continue; > + urcu_adaptative_wake_up(&wt->wait_futex); > + } > + > +gp_end: > /* > * Finish waiting for reader threads before letting the old ptr being > * freed. > @@ -286,6 +402,9 @@ void synchronize_rcu(void) > { > CDS_LIST_HEAD(qsreaders); > unsigned long was_online; > + struct gp_waiters_thread gp_waiters_thread; > + struct cds_wfs_head *gp_waiters_head; > + struct cds_wfs_node *waiters_iter, *waiters_iter_n; > > was_online = URCU_TLS(rcu_reader).ctr; > > @@ -299,7 +418,26 @@ void synchronize_rcu(void) > else > cmm_smp_mb(); > > + /* > + * Add ourself to gp_waiters stack of threads awaiting to wait > + * for a grace period. Proceed to perform the grace period only > + * if we are the first thread added into the stack. > + */ > + cds_wfs_node_init(&gp_waiters_thread.node); > + gp_waiters_thread.wait_futex = AWAKE_WAITING; > + if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { > + /* Not first in stack: will be awakened by another thread. */ > + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); > + goto gp_end; > + } > + > mutex_lock(&rcu_gp_lock); > + > + /* > + * Pop all waiters into our local stack head. > + */ > + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); > + > if (cds_list_empty(®istry)) > goto out; > > @@ -334,6 +472,19 @@ void synchronize_rcu(void) > out: > mutex_unlock(&rcu_gp_lock); > > + /* Wake all waiters in our stack head, excluding ourself. */ > + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, > + waiters_iter_n) { > + struct gp_waiters_thread *wt; > + > + wt = caa_container_of(waiters_iter, > + struct gp_waiters_thread, node); > + if (wt == &gp_waiters_thread) > + continue; > + urcu_adaptative_wake_up(&wt->wait_futex); > + } > + > +gp_end: > if (was_online) > rcu_thread_online(); > else From laijs at cn.fujitsu.com Wed Nov 21 03:42:08 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Wed, 21 Nov 2012 16:42:08 +0800 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> Message-ID: <50AC93E0.1050204@cn.fujitsu.com> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > A carefully crafted splice operation does not need to use an external > mutex to synchronize against other splice operations. > > The trick is atomically exchange the head next pointer with > NULL. If the pointer we replaced was NULL, it means the queue was > possibly empty. If head next was not NULL, by setting head to NULL, we > ensure that concurrent splice operations are going to see an empty > queue, even if concurrent enqueue operations move tail further. This > means that as long as we are within splice, after setting head to NULL, > but before moving tail back to head, concurrent splice operations will > always see an empty queue, therefore acting as mutual exclusion. > > If exchange returns a NULL head, we confirm that it was indeed empty by > checking if the tail pointer points to the head node, busy-waiting if > necessary. > > Then the last step is to move the tail pointer to head. At that point, > enqueuers are going to start enqueuing at head again, and other splice > operations will be able to proceed. > > Signed-off-by: Mathieu Desnoyers > --- > urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ > urcu/wfcqueue.h | 40 ++++++++++++++++++---------- > wfcqueue.c | 2 +- > 3 files changed, 79 insertions(+), 31 deletions(-) > > diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > index 8774c03..4b2de50 100644 > --- a/urcu/static/wfcqueue.h > +++ b/urcu/static/wfcqueue.h > @@ -46,15 +46,30 @@ extern "C" { > * half-wait-free/half-blocking queue implementation done by Paul E. > * McKenney. > * > - * Mutual exclusion of __cds_wfcq_* API > - * > - * Unless otherwise stated, the caller must ensure mutual exclusion of > - * queue update operations "dequeue" and "splice" (for source queue). > - * Queue read operations "first" and "next", which are used by > - * "for_each" iterations, need to be protected against concurrent > - * "dequeue" and "splice" (for source queue) by the caller. > - * "enqueue", "splice" (for destination queue), and "empty" are the only > - * operations that can be used without any mutual exclusion. > + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > + * > + * Synchronization table: > + * > + * External synchronization techniques described in the API below is > + * required between pairs marked with "X". No external synchronization > + * required between pairs marked with "-". > + * > + * Legend: > + * [1] cds_wfcq_enqueue > + * [2] __cds_wfcq_splice (destination queue) > + * [3] __cds_wfcq_dequeue > + * [4] __cds_wfcq_splice (source queue) > + * [5] __cds_wfcq_first > + * [6] __cds_wfcq_next > + * > + * [1] [2] [3] [4] [5] [6] > + * [1] - - - - - - > + * [2] - - - - - - > + * [3] - - X X X X > + * [4] - - X - X X > + * [5] - - X X - - > + * [6] - - X X - - > + * > * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > * > * For convenience, cds_wfcq_dequeue_blocking() and > @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, > return ___cds_wfcq_dequeue(head, tail, 0); > } > > +/* > + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. > + * > + * Dequeue all nodes from src_q. > + * dest_q must be already initialized. > + * Mutual exclusion for src_q should be ensured by the caller as > + * specified in the "Synchronisation table". > + * Returns enum cds_wfcq_ret which indicates the state of the src or > + * dest queue. > + */ > static inline enum cds_wfcq_ret > ___cds_wfcq_splice( > struct cds_wfcq_head *dest_q_head, > @@ -408,14 +433,26 @@ ___cds_wfcq_splice( > int blocking) > { > struct cds_wfcq_node *head, *tail; > + int attempt = 0; +again: > > if (_cds_wfcq_empty(src_q_head, src_q_tail)) > return CDS_WFCQ_RET_SRC_EMPTY; > > - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); > - if (head == CDS_WFCQ_WOULDBLOCK) > - return CDS_WFCQ_RET_WOULDBLOCK; > - _cds_wfcq_node_init(&src_q_head->node); > + for (;;) { > + head = uatomic_xchg(&src_q_head->node.next, NULL); > + if (head) > + break; /* non-empty */ > + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) > + return CDS_WFCQ_RET_SRC_EMPTY; > + if (!blocking) > + return CDS_WFCQ_RET_WOULDBLOCK; > + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { > + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > + attempt = 0; > + } else { > + caa_cpu_relax(); > + } > + } Is it OK: - _cds_wfcq_node_init(&src_q_head->node); + head = uatomic_xchg(&src_q_head->node.next, NULL); + if (!head) + goto again; > > /* > * Memory barrier implied before uatomic_xchg() orders store to > @@ -435,14 +472,13 @@ ___cds_wfcq_splice( > return CDS_WFCQ_RET_DEST_EMPTY; > } > > - > /* > * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > * > * Dequeue all nodes from src_q. > * dest_q must be already initialized. > - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > - * by the caller. > + * Mutual exclusion for src_q should be ensured by the caller as > + * specified in the "Synchronisation table". > * Returns enum cds_wfcq_ret which indicates the state of the src or > * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > */ > diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h > index ddf6b87..d9ec534 100644 > --- a/urcu/wfcqueue.h > +++ b/urcu/wfcqueue.h > @@ -46,7 +46,7 @@ extern "C" { > #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) > > enum cds_wfcq_ret { > - CDS_WFCQ_RET_WOULDBLOCK = -1, > + CDS_WFCQ_RET_WOULDBLOCK = -1, > CDS_WFCQ_RET_DEST_EMPTY = 0, > CDS_WFCQ_RET_DEST_NON_EMPTY = 1, > CDS_WFCQ_RET_SRC_EMPTY = 2, > @@ -110,13 +110,28 @@ struct cds_wfcq_tail { > /* > * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > * > - * Unless otherwise stated, the caller must ensure mutual exclusion of > - * queue update operations "dequeue" and "splice" (for source queue). > - * Queue read operations "first" and "next", which are used by > - * "for_each" iterations, need to be protected against concurrent > - * "dequeue" and "splice" (for source queue) by the caller. > - * "enqueue", "splice" (for destination queue), and "empty" are the only > - * operations that can be used without any mutual exclusion. > + * Synchronization table: > + * > + * External synchronization techniques described in the API below is > + * required between pairs marked with "X". No external synchronization > + * required between pairs marked with "-". > + * > + * Legend: > + * [1] cds_wfcq_enqueue > + * [2] __cds_wfcq_splice (destination queue) > + * [3] __cds_wfcq_dequeue > + * [4] __cds_wfcq_splice (source queue) > + * [5] __cds_wfcq_first > + * [6] __cds_wfcq_next > + * > + * [1] [2] [3] [4] [5] [6] > + * [1] - - - - - - > + * [2] - - - - - - > + * [3] - - X X X X > + * [4] - - X - X X > + * [5] - - X X - - > + * [6] - - X X - - > + * > * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > * > * For convenience, cds_wfcq_dequeue_blocking() and > @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > * > * Dequeue all nodes from src_q. > * dest_q must be already initialized. > - * Content written into the node before enqueue is guaranteed to be > - * consistent, but no other memory ordering is ensured. > - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > - * by the caller. > - * > + * Mutual exclusion for src_q should be ensured by the caller as > + * specified in the "Synchronisation table". > * Returns enum cds_wfcq_ret which indicates the state of the src or > - * dest queue. Cannot block. > + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > */ > extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( > struct cds_wfcq_head *dest_q_head, > diff --git a/wfcqueue.c b/wfcqueue.c > index 207df95..ab0eb93 100644 > --- a/wfcqueue.c > +++ b/wfcqueue.c > @@ -1,7 +1,7 @@ > /* > * wfcqueue.c > * > - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue > + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue > * > * Copyright 2010-2012 - Mathieu Desnoyers > * Copyright 2011-2012 - Lai Jiangshan From mathieu.desnoyers at efficios.com Wed Nov 21 09:37:16 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 21 Nov 2012 09:37:16 -0500 Subject: [lttng-dev] [PATCH 01/16] Fix: wfcqueue nonblocking dequeue In-Reply-To: <50AC8BDA.9080309@cn.fujitsu.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-2-git-send-email-mathieu.desnoyers@efficios.com> <50AC8BDA.9080309@cn.fujitsu.com> Message-ID: <20121121143716.GA21518@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > > Failures were not handled in the nonblocking dequeue implementation. > > > > Signed-off-by: Mathieu Desnoyers > > --- > > urcu/static/wfcqueue.h | 11 +++++++++++ > > 1 file changed, 11 insertions(+) > > > > diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > > index 8733771..a284b58 100644 > > --- a/urcu/static/wfcqueue.h > > +++ b/urcu/static/wfcqueue.h > > @@ -312,6 +312,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > return NULL; > > > > node = ___cds_wfcq_node_sync_next(&head->node, blocking); > > + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) > > + return CDS_WFCQ_WOULDBLOCK; > > > > if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { > > /* > > @@ -332,6 +334,15 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, > > if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) > > return node; > > Is it this simpler? > we had just loaded node->next via "if ((next = CMM_LOAD_SHARED(node->next)) == NULL)" > > > + if (!blocking) > + return CDS_WFCQ_WOULDBLOCK > > > next = ___cds_wfcq_node_sync_next(node, blocking); > > and remove the following. So let's see. We have met the condition "if ((next = CMM_LOAD_SHARED(node->next)) == NULL) {" Therefore, it means that it appears, at that point, that the queue has only one node. So usually, after this test succeeds, we'll have to set the queue state to empty. There is only one case where this will not be done: if a concurrent enqueue adds a node between this test and the cmpxchg that follows. In that case, we'll notice this because cmpxchg fails, and instead of setting the queue to "empty", we'll simply wait for enqueue to complete adding the new node, and move head forward. The approach you propose is to consider that if cmpxchg fails, we will very likely have to block. Well, that would skip a call to ___cds_wfcq_node_sync_next, and semantically would be still right, because the only way cmpxchg can fail is if the tail pointer is being changed concurrently, which would typically make us block. However, we'd still need to perform "head->node.next = node;" before we return CDS_WFCQ_WOULDBLOCK, because _cds_wfcq_node_init() has already set the head next pointer to NULL, and we need to undo that. Thoughts ? Thanks, Mathieu > > > + /* > > + * In nonblocking mode, if we would need to block to > > + * get node's next, set the head next node pointer > > + * (currently NULL) back to its original value. > > + */ > > + if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { > > + head->node.next = node; > > + return CDS_WFCQ_WOULDBLOCK; > > + } > > } > > > > /* -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 21 10:18:24 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 21 Nov 2012 10:18:24 -0500 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <50AC93E0.1050204@cn.fujitsu.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> <50AC93E0.1050204@cn.fujitsu.com> Message-ID: <20121121151823.GB21518@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > > A carefully crafted splice operation does not need to use an external > > mutex to synchronize against other splice operations. > > > > The trick is atomically exchange the head next pointer with > > NULL. If the pointer we replaced was NULL, it means the queue was > > possibly empty. If head next was not NULL, by setting head to NULL, we > > ensure that concurrent splice operations are going to see an empty > > queue, even if concurrent enqueue operations move tail further. This > > means that as long as we are within splice, after setting head to NULL, > > but before moving tail back to head, concurrent splice operations will > > always see an empty queue, therefore acting as mutual exclusion. > > > > If exchange returns a NULL head, we confirm that it was indeed empty by > > checking if the tail pointer points to the head node, busy-waiting if > > necessary. > > > > Then the last step is to move the tail pointer to head. At that point, > > enqueuers are going to start enqueuing at head again, and other splice > > operations will be able to proceed. > > > > Signed-off-by: Mathieu Desnoyers > > --- > > urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ > > urcu/wfcqueue.h | 40 ++++++++++++++++++---------- > > wfcqueue.c | 2 +- > > 3 files changed, 79 insertions(+), 31 deletions(-) > > > > diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > > index 8774c03..4b2de50 100644 > > --- a/urcu/static/wfcqueue.h > > +++ b/urcu/static/wfcqueue.h > > @@ -46,15 +46,30 @@ extern "C" { > > * half-wait-free/half-blocking queue implementation done by Paul E. > > * McKenney. > > * > > - * Mutual exclusion of __cds_wfcq_* API > > - * > > - * Unless otherwise stated, the caller must ensure mutual exclusion of > > - * queue update operations "dequeue" and "splice" (for source queue). > > - * Queue read operations "first" and "next", which are used by > > - * "for_each" iterations, need to be protected against concurrent > > - * "dequeue" and "splice" (for source queue) by the caller. > > - * "enqueue", "splice" (for destination queue), and "empty" are the only > > - * operations that can be used without any mutual exclusion. > > + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > > + * > > + * Synchronization table: > > + * > > + * External synchronization techniques described in the API below is > > + * required between pairs marked with "X". No external synchronization > > + * required between pairs marked with "-". > > + * > > + * Legend: > > + * [1] cds_wfcq_enqueue > > + * [2] __cds_wfcq_splice (destination queue) > > + * [3] __cds_wfcq_dequeue > > + * [4] __cds_wfcq_splice (source queue) > > + * [5] __cds_wfcq_first > > + * [6] __cds_wfcq_next > > + * > > + * [1] [2] [3] [4] [5] [6] > > + * [1] - - - - - - > > + * [2] - - - - - - > > + * [3] - - X X X X > > + * [4] - - X - X X > > + * [5] - - X X - - > > + * [6] - - X X - - > > + * > > * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > > * > > * For convenience, cds_wfcq_dequeue_blocking() and > > @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, > > return ___cds_wfcq_dequeue(head, tail, 0); > > } > > > > +/* > > + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. > > + * > > + * Dequeue all nodes from src_q. > > + * dest_q must be already initialized. > > + * Mutual exclusion for src_q should be ensured by the caller as > > + * specified in the "Synchronisation table". > > + * Returns enum cds_wfcq_ret which indicates the state of the src or > > + * dest queue. > > + */ > > static inline enum cds_wfcq_ret > > ___cds_wfcq_splice( > > struct cds_wfcq_head *dest_q_head, > > @@ -408,14 +433,26 @@ ___cds_wfcq_splice( > > int blocking) > > { > > struct cds_wfcq_node *head, *tail; > > + int attempt = 0; > > +again: > > > > > if (_cds_wfcq_empty(src_q_head, src_q_tail)) > > return CDS_WFCQ_RET_SRC_EMPTY; > > > > - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); > > - if (head == CDS_WFCQ_WOULDBLOCK) > > - return CDS_WFCQ_RET_WOULDBLOCK; > > - _cds_wfcq_node_init(&src_q_head->node); > > + for (;;) { > > + head = uatomic_xchg(&src_q_head->node.next, NULL); > > + if (head) > > + break; /* non-empty */ > > + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) > > + return CDS_WFCQ_RET_SRC_EMPTY; > > + if (!blocking) > > + return CDS_WFCQ_RET_WOULDBLOCK; > > + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { > > + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > > + attempt = 0; > > + } else { > > + caa_cpu_relax(); > > + } > > + } > > > Is it OK: > > - _cds_wfcq_node_init(&src_q_head->node); > + head = uatomic_xchg(&src_q_head->node.next, NULL); > + if (!head) > + goto again; You are right that we can simplify the code a bit by re-using _cds_wfcq_empty() to test validate emptiness of the source queue, rather than open-code it. The only issue here is that the busy-loop (goto again) will not invoke caa_cpu_relax(), nor do adaptative waiting like ___cds_wfcq_node_sync_next() normally does. Also, it does not check for blocking/non-blocking caller. Also, whenever possible, I like to have for () or do/while constructs in place to make it clear that we can loop. So a modification of your proposal would look like: /* Return 1 if nonblocking and needs to block, 0 otherwise */ static inline bool ___cds_wfcq_busy_wait(int *attempt, int blocking) { if (!blocking) return 1; if (+attempt >= WFCQ_ADAPT_ATTEMPTS) { poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ attempt = 0; } else { caa_cpu_relax(); } return 0; } [...] struct cds_wfcq_node *head, *tail; int attempt = 0; for (;;) { if (_cds_wfcq_empty(src_q_head, src_q_tail)) return CDS_WFCQ_RET_SRC_EMPTY; head = uatomic_xchg(&src_q_head->node.next, NULL); if (head) break; if (___cds_wfcq_busy_wait(&attempt, blocking)) return CDS_WFCQ_RET_WOULDBLOCK; } Thoughts ? Thanks, Mathieu > > > > > /* > > * Memory barrier implied before uatomic_xchg() orders store to > > @@ -435,14 +472,13 @@ ___cds_wfcq_splice( > > return CDS_WFCQ_RET_DEST_EMPTY; > > } > > > > - > > /* > > * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > > * > > * Dequeue all nodes from src_q. > > * dest_q must be already initialized. > > - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > > - * by the caller. > > + * Mutual exclusion for src_q should be ensured by the caller as > > + * specified in the "Synchronisation table". > > * Returns enum cds_wfcq_ret which indicates the state of the src or > > * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > > */ > > diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h > > index ddf6b87..d9ec534 100644 > > --- a/urcu/wfcqueue.h > > +++ b/urcu/wfcqueue.h > > @@ -46,7 +46,7 @@ extern "C" { > > #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) > > > > enum cds_wfcq_ret { > > - CDS_WFCQ_RET_WOULDBLOCK = -1, > > + CDS_WFCQ_RET_WOULDBLOCK = -1, > > CDS_WFCQ_RET_DEST_EMPTY = 0, > > CDS_WFCQ_RET_DEST_NON_EMPTY = 1, > > CDS_WFCQ_RET_SRC_EMPTY = 2, > > @@ -110,13 +110,28 @@ struct cds_wfcq_tail { > > /* > > * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > > * > > - * Unless otherwise stated, the caller must ensure mutual exclusion of > > - * queue update operations "dequeue" and "splice" (for source queue). > > - * Queue read operations "first" and "next", which are used by > > - * "for_each" iterations, need to be protected against concurrent > > - * "dequeue" and "splice" (for source queue) by the caller. > > - * "enqueue", "splice" (for destination queue), and "empty" are the only > > - * operations that can be used without any mutual exclusion. > > + * Synchronization table: > > + * > > + * External synchronization techniques described in the API below is > > + * required between pairs marked with "X". No external synchronization > > + * required between pairs marked with "-". > > + * > > + * Legend: > > + * [1] cds_wfcq_enqueue > > + * [2] __cds_wfcq_splice (destination queue) > > + * [3] __cds_wfcq_dequeue > > + * [4] __cds_wfcq_splice (source queue) > > + * [5] __cds_wfcq_first > > + * [6] __cds_wfcq_next > > + * > > + * [1] [2] [3] [4] [5] [6] > > + * [1] - - - - - - > > + * [2] - - - - - - > > + * [3] - - X X X X > > + * [4] - - X - X X > > + * [5] - - X X - - > > + * [6] - - X X - - > > + * > > * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > > * > > * For convenience, cds_wfcq_dequeue_blocking() and > > @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > > * > > * Dequeue all nodes from src_q. > > * dest_q must be already initialized. > > - * Content written into the node before enqueue is guaranteed to be > > - * consistent, but no other memory ordering is ensured. > > - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > > - * by the caller. > > - * > > + * Mutual exclusion for src_q should be ensured by the caller as > > + * specified in the "Synchronisation table". > > * Returns enum cds_wfcq_ret which indicates the state of the src or > > - * dest queue. Cannot block. > > + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > > */ > > extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( > > struct cds_wfcq_head *dest_q_head, > > diff --git a/wfcqueue.c b/wfcqueue.c > > index 207df95..ab0eb93 100644 > > --- a/wfcqueue.c > > +++ b/wfcqueue.c > > @@ -1,7 +1,7 @@ > > /* > > * wfcqueue.c > > * > > - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue > > + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue > > * > > * Copyright 2010-2012 - Mathieu Desnoyers > > * Copyright 2011-2012 - Lai Jiangshan > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 21 13:33:04 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 21 Nov 2012 13:33:04 -0500 Subject: [lttng-dev] [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <50AC8F56.6040109@cn.fujitsu.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> <50AC8F56.6040109@cn.fujitsu.com> Message-ID: <20121121183304.GA25932@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > Could you delay 14~16 for 40 days if I don't implement it in 40 days? I'm curious to know more about the changes you are planning. Is that another way to implement grace periods that would allow multiple threads to execute synchronize_rcu() concurrently ? Please note that changes in these algorithms will need to go through very strict review/validation/verification. So I expect that if it takes 40 days to implement, we can plan at least 3-4 months of validation work. With that in mind, would it make sense to merge the batching approach in the meantime ? The advantage of the batching approach is that it does not touch the core of the synchronization algorithm. Thoughts ? Thanks, Mathieu > > On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > > Here are benchmarks on batching of synchronize_rcu(), and it leads to > > very interesting scalability improvement and speedups, e.g., on a > > 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > > threads, each updater using synchronize_rcu()): > > > > * Serialized grace periods : > > > > ./test_urcu_qsbr 4 20 20 > > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 20 wdelay 0 > > nr_reads 20251412728 nr_writes 1826331 nr_ops 20253239059 > > > > * Batched grace periods : > > > > ./test_urcu_qsbr 4 20 20 > > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 20 wdelay 0 > > nr_reads 15141994746 nr_writes 9382515 nr_ops 15151377261 > > > > For a 9382515/1826331 = 5.13 speedup for 20 updaters. > > > > Of course, we can see that readers have slowed down, probably due to > > increased update traffic, given there is no change to the read-side code > > whatsoever. > > > > Now let's see the penality of managing the stack for single-updater. > > With 4 readers, single updater: > > > > * Serialized grace periods : > > > > ./test_urcu_qsbr 4 1 20 > > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 19240784755 nr_writes 2130839 nr_ops 19242915594 > > > > * Batched grace periods : > > > > ./test_urcu_qsbr 4 1 20 > > SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 19160162768 nr_writes 2253068 nr_ops 1916241583 > > > > 2253068 vs 2137036 -> a couple of runs show that this difference lost in > > the noise for single updater. > > > > CC: Paul E. McKenney > > CC: Lai Jiangshan > > CC: Alan Stern > > Signed-off-by: Mathieu Desnoyers > > --- > > urcu-qsbr.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 151 insertions(+) > > > > diff --git a/urcu-qsbr.c b/urcu-qsbr.c > > index 5b341b5..7f747ed 100644 > > --- a/urcu-qsbr.c > > +++ b/urcu-qsbr.c > > @@ -36,6 +36,7 @@ > > #include > > > > #include "urcu/wfcqueue.h" > > +#include "urcu/wfstack.h" > > #include "urcu/map/urcu-qsbr.h" > > #define BUILD_QSBR_LIB > > #include "urcu/static/urcu-qsbr.h" > > @@ -78,6 +79,35 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > > > > static CDS_LIST_HEAD(registry); > > > > +/* > > + * Number of busy-loop attempts before waiting on futex for grace period > > + * batching. > > + */ > > +#define RCU_AWAKE_ATTEMPTS 1000 > > + > > +enum adapt_wakeup_state { > > + /* AWAKE_WAITING is compared directly (futex compares it). */ > > + AWAKE_WAITING = 0, > > + /* non-zero are used as masks. */ > > + AWAKE_WAKEUP = (1 << 0), > > + AWAKE_AWAKENED = (1 << 1), > > + AWAKE_TEARDOWN = (1 << 2), > > +}; > > + > > +struct gp_waiters_thread { > > + struct cds_wfs_node node; > > + int32_t wait_futex; > > +}; > > + > > +/* > > + * Stack keeping threads awaiting to wait for a grace period. Contains > > + * struct gp_waiters_thread objects. > > + */ > > +static struct cds_wfs_stack gp_waiters = { > > + .head = CDS_WFS_END, > > + .lock = PTHREAD_MUTEX_INITIALIZER, > > +}; > > + > > static void mutex_lock(pthread_mutex_t *mutex) > > { > > int ret; > > @@ -116,6 +146,58 @@ static void wait_gp(void) > > NULL, NULL, 0); > > } > > > > +/* > > + * Note: urcu_adaptative_wake_up needs "value" to stay allocated > > + * throughout its execution. In this scheme, the waiter owns the futex > > + * memory, and we only allow it to free this memory when it receives the > > + * AWAKE_TEARDOWN flag. > > + */ > > +static void urcu_adaptative_wake_up(int32_t *value) > > +{ > > + cmm_smp_mb(); > > + assert(uatomic_read(value) == AWAKE_WAITING); > > + uatomic_set(value, AWAKE_WAKEUP); > > + if (!(uatomic_read(value) & AWAKE_AWAKENED)) > > + futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); > > + /* Allow teardown of "value" memory. */ > > + uatomic_or(value, AWAKE_TEARDOWN); > > +} > > + > > +/* > > + * Caller must initialize "value" to AWAKE_WAITING before passing its > > + * memory to waker thread. > > + */ > > +static void urcu_adaptative_busy_wait(int32_t *value) > > +{ > > + unsigned int i; > > + > > + /* Load and test condition before read futex */ > > + cmm_smp_rmb(); > > + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { > > + if (uatomic_read(value) != AWAKE_WAITING) > > + goto skip_futex_wait; > > + caa_cpu_relax(); > > + } > > + futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); > > +skip_futex_wait: > > + > > + /* Tell waker thread than we are awakened. */ > > + uatomic_or(value, AWAKE_AWAKENED); > > + > > + /* > > + * Wait until waker thread lets us know it's ok to tear down > > + * memory allocated for value. > > + */ > > + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { > > + if (uatomic_read(value) & AWAKE_TEARDOWN) > > + break; > > + caa_cpu_relax(); > > + } > > + while (!(uatomic_read(value) & AWAKE_TEARDOWN)) > > + poll(NULL, 0, 10); > > + assert(uatomic_read(value) & AWAKE_TEARDOWN); > > +} > > + > > static void wait_for_readers(struct cds_list_head *input_readers, > > struct cds_list_head *cur_snap_readers, > > struct cds_list_head *qsreaders) > > @@ -198,6 +280,9 @@ void synchronize_rcu(void) > > CDS_LIST_HEAD(cur_snap_readers); > > CDS_LIST_HEAD(qsreaders); > > unsigned long was_online; > > + struct gp_waiters_thread gp_waiters_thread; > > + struct cds_wfs_head *gp_waiters_head; > > + struct cds_wfs_node *waiters_iter, *waiters_iter_n; > > > > was_online = URCU_TLS(rcu_reader).ctr; > > > > @@ -214,8 +299,26 @@ void synchronize_rcu(void) > > else > > cmm_smp_mb(); > > > > + /* > > + * Add ourself to gp_waiters stack of threads awaiting to wait > > + * for a grace period. Proceed to perform the grace period only > > + * if we are the first thread added into the stack. > > + */ > > + cds_wfs_node_init(&gp_waiters_thread.node); > > + gp_waiters_thread.wait_futex = AWAKE_WAITING; > > + if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { > > + /* Not first in stack: will be awakened by another thread. */ > > + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); > > + goto gp_end; > > + } > > + > > mutex_lock(&rcu_gp_lock); > > > > + /* > > + * Pop all waiters into our local stack head. > > + */ > > + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); > > + > > if (cds_list_empty(®istry)) > > goto out; > > > > @@ -272,6 +375,19 @@ void synchronize_rcu(void) > > out: > > mutex_unlock(&rcu_gp_lock); > > > > + /* Wake all waiters in our stack head, excluding ourself. */ > > + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, > > + waiters_iter_n) { > > + struct gp_waiters_thread *wt; > > + > > + wt = caa_container_of(waiters_iter, > > + struct gp_waiters_thread, node); > > + if (wt == &gp_waiters_thread) > > + continue; > > + urcu_adaptative_wake_up(&wt->wait_futex); > > + } > > + > > +gp_end: > > /* > > * Finish waiting for reader threads before letting the old ptr being > > * freed. > > @@ -286,6 +402,9 @@ void synchronize_rcu(void) > > { > > CDS_LIST_HEAD(qsreaders); > > unsigned long was_online; > > + struct gp_waiters_thread gp_waiters_thread; > > + struct cds_wfs_head *gp_waiters_head; > > + struct cds_wfs_node *waiters_iter, *waiters_iter_n; > > > > was_online = URCU_TLS(rcu_reader).ctr; > > > > @@ -299,7 +418,26 @@ void synchronize_rcu(void) > > else > > cmm_smp_mb(); > > > > + /* > > + * Add ourself to gp_waiters stack of threads awaiting to wait > > + * for a grace period. Proceed to perform the grace period only > > + * if we are the first thread added into the stack. > > + */ > > + cds_wfs_node_init(&gp_waiters_thread.node); > > + gp_waiters_thread.wait_futex = AWAKE_WAITING; > > + if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { > > + /* Not first in stack: will be awakened by another thread. */ > > + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); > > + goto gp_end; > > + } > > + > > mutex_lock(&rcu_gp_lock); > > + > > + /* > > + * Pop all waiters into our local stack head. > > + */ > > + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); > > + > > if (cds_list_empty(®istry)) > > goto out; > > > > @@ -334,6 +472,19 @@ void synchronize_rcu(void) > > out: > > mutex_unlock(&rcu_gp_lock); > > > > + /* Wake all waiters in our stack head, excluding ourself. */ > > + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, > > + waiters_iter_n) { > > + struct gp_waiters_thread *wt; > > + > > + wt = caa_container_of(waiters_iter, > > + struct gp_waiters_thread, node); > > + if (wt == &gp_waiters_thread) > > + continue; > > + urcu_adaptative_wake_up(&wt->wait_futex); > > + } > > + > > +gp_end: > > if (was_online) > > rcu_thread_online(); > > else > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From laijs at cn.fujitsu.com Thu Nov 22 03:37:23 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Thu, 22 Nov 2012 16:37:23 +0800 Subject: [lttng-dev] [PATCH 01/16] Fix: wfcqueue nonblocking dequeue In-Reply-To: <20121121143716.GA21518@Krystal> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-2-git-send-email-mathieu.desnoyers@efficios.com> <50AC8BDA.9080309@cn.fujitsu.com> <20121121143716.GA21518@Krystal> Message-ID: <50ADE443.50904@cn.fujitsu.com> On 11/21/2012 10:37 PM, Mathieu Desnoyers wrote: > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: >> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: >>> Failures were not handled in the nonblocking dequeue implementation. >>> >>> Signed-off-by: Mathieu Desnoyers >>> --- >>> urcu/static/wfcqueue.h | 11 +++++++++++ >>> 1 file changed, 11 insertions(+) >>> >>> diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h >>> index 8733771..a284b58 100644 >>> --- a/urcu/static/wfcqueue.h >>> +++ b/urcu/static/wfcqueue.h >>> @@ -312,6 +312,8 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, >>> return NULL; >>> >>> node = ___cds_wfcq_node_sync_next(&head->node, blocking); >>> + if (!blocking && node == CDS_WFCQ_WOULDBLOCK) >>> + return CDS_WFCQ_WOULDBLOCK; >>> >>> if ((next = CMM_LOAD_SHARED(node->next)) == NULL) { >>> /* >>> @@ -332,6 +334,15 @@ ___cds_wfcq_dequeue(struct cds_wfcq_head *head, >>> if (uatomic_cmpxchg(&tail->p, node, &head->node) == node) >>> return node; >> >> Is it this simpler? >> we had just loaded node->next via "if ((next = CMM_LOAD_SHARED(node->next)) == NULL)" >> >> >> + if (!blocking) >> + return CDS_WFCQ_WOULDBLOCK >> >>> next = ___cds_wfcq_node_sync_next(node, blocking); >> >> and remove the following. > > So let's see. We have met the condition > "if ((next = CMM_LOAD_SHARED(node->next)) == NULL) {" > > Therefore, it means that it appears, at that point, that the queue has > only one node. So usually, after this test succeeds, we'll have to set > the queue state to empty. There is only one case where this will not be > done: if a concurrent enqueue adds a node between this test and the > cmpxchg that follows. In that case, we'll notice this because cmpxchg > fails, and instead of setting the queue to "empty", we'll simply wait > for enqueue to complete adding the new node, and move head forward. > > The approach you propose is to consider that if cmpxchg fails, we > will very likely have to block. Well, that would skip a call to > ___cds_wfcq_node_sync_next, and semantically would be still right, > because the only way cmpxchg can fail is if the tail pointer is being > changed concurrently, which would typically make us block. > > However, we'd still need to perform "head->node.next = node;" before we > return CDS_WFCQ_WOULDBLOCK, because _cds_wfcq_node_init() has already > set the head next pointer to NULL, and we need to undo that. > You are right, I just proposed some noise which is not simple as I claimed. sorry. Thanks, Lai > >> >>> + /* >>> + * In nonblocking mode, if we would need to block to >>> + * get node's next, set the head next node pointer >>> + * (currently NULL) back to its original value. >>> + */ >>> + if (!blocking && next == CDS_WFCQ_WOULDBLOCK) { >>> + head->node.next = node; >>> + return CDS_WFCQ_WOULDBLOCK; >>> + } >>> } >>> >>> /* > From laijs at cn.fujitsu.com Thu Nov 22 03:50:55 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Thu, 22 Nov 2012 16:50:55 +0800 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <20121121151823.GB21518@Krystal> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> <50AC93E0.1050204@cn.fujitsu.com> <20121121151823.GB21518@Krystal> Message-ID: <50ADE76F.7090006@cn.fujitsu.com> On 11/21/2012 11:18 PM, Mathieu Desnoyers wrote: > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: >> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: >>> A carefully crafted splice operation does not need to use an external >>> mutex to synchronize against other splice operations. >>> >>> The trick is atomically exchange the head next pointer with >>> NULL. If the pointer we replaced was NULL, it means the queue was >>> possibly empty. If head next was not NULL, by setting head to NULL, we >>> ensure that concurrent splice operations are going to see an empty >>> queue, even if concurrent enqueue operations move tail further. This >>> means that as long as we are within splice, after setting head to NULL, >>> but before moving tail back to head, concurrent splice operations will >>> always see an empty queue, therefore acting as mutual exclusion. >>> >>> If exchange returns a NULL head, we confirm that it was indeed empty by >>> checking if the tail pointer points to the head node, busy-waiting if >>> necessary. >>> >>> Then the last step is to move the tail pointer to head. At that point, >>> enqueuers are going to start enqueuing at head again, and other splice >>> operations will be able to proceed. >>> >>> Signed-off-by: Mathieu Desnoyers >>> --- >>> urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ >>> urcu/wfcqueue.h | 40 ++++++++++++++++++---------- >>> wfcqueue.c | 2 +- >>> 3 files changed, 79 insertions(+), 31 deletions(-) >>> >>> diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h >>> index 8774c03..4b2de50 100644 >>> --- a/urcu/static/wfcqueue.h >>> +++ b/urcu/static/wfcqueue.h >>> @@ -46,15 +46,30 @@ extern "C" { >>> * half-wait-free/half-blocking queue implementation done by Paul E. >>> * McKenney. >>> * >>> - * Mutual exclusion of __cds_wfcq_* API >>> - * >>> - * Unless otherwise stated, the caller must ensure mutual exclusion of >>> - * queue update operations "dequeue" and "splice" (for source queue). >>> - * Queue read operations "first" and "next", which are used by >>> - * "for_each" iterations, need to be protected against concurrent >>> - * "dequeue" and "splice" (for source queue) by the caller. >>> - * "enqueue", "splice" (for destination queue), and "empty" are the only >>> - * operations that can be used without any mutual exclusion. >>> + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API >>> + * >>> + * Synchronization table: >>> + * >>> + * External synchronization techniques described in the API below is >>> + * required between pairs marked with "X". No external synchronization >>> + * required between pairs marked with "-". >>> + * >>> + * Legend: >>> + * [1] cds_wfcq_enqueue >>> + * [2] __cds_wfcq_splice (destination queue) >>> + * [3] __cds_wfcq_dequeue >>> + * [4] __cds_wfcq_splice (source queue) >>> + * [5] __cds_wfcq_first >>> + * [6] __cds_wfcq_next >>> + * >>> + * [1] [2] [3] [4] [5] [6] >>> + * [1] - - - - - - >>> + * [2] - - - - - - >>> + * [3] - - X X X X >>> + * [4] - - X - X X >>> + * [5] - - X X - - >>> + * [6] - - X X - - >>> + * >>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). >>> * >>> * For convenience, cds_wfcq_dequeue_blocking() and >>> @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, >>> return ___cds_wfcq_dequeue(head, tail, 0); >>> } >>> >>> +/* >>> + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. >>> + * >>> + * Dequeue all nodes from src_q. >>> + * dest_q must be already initialized. >>> + * Mutual exclusion for src_q should be ensured by the caller as >>> + * specified in the "Synchronisation table". >>> + * Returns enum cds_wfcq_ret which indicates the state of the src or >>> + * dest queue. >>> + */ >>> static inline enum cds_wfcq_ret >>> ___cds_wfcq_splice( >>> struct cds_wfcq_head *dest_q_head, >>> @@ -408,14 +433,26 @@ ___cds_wfcq_splice( >>> int blocking) >>> { >>> struct cds_wfcq_node *head, *tail; >>> + int attempt = 0; >> >> +again: >> >>> >>> if (_cds_wfcq_empty(src_q_head, src_q_tail)) >>> return CDS_WFCQ_RET_SRC_EMPTY; >>> >>> - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); >>> - if (head == CDS_WFCQ_WOULDBLOCK) >>> - return CDS_WFCQ_RET_WOULDBLOCK; >>> - _cds_wfcq_node_init(&src_q_head->node); >>> + for (;;) { >>> + head = uatomic_xchg(&src_q_head->node.next, NULL); >>> + if (head) >>> + break; /* non-empty */ >>> + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) >>> + return CDS_WFCQ_RET_SRC_EMPTY; >>> + if (!blocking) >>> + return CDS_WFCQ_RET_WOULDBLOCK; >>> + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { >>> + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ >>> + attempt = 0; >>> + } else { >>> + caa_cpu_relax(); >>> + } >>> + } >> >> >> Is it OK: >> >> - _cds_wfcq_node_init(&src_q_head->node); >> + head = uatomic_xchg(&src_q_head->node.next, NULL); >> + if (!head) >> + goto again; > > You are right that we can simplify the code a bit by re-using > _cds_wfcq_empty() to test validate emptiness of the source queue, rather > than open-code it. > > The only issue here is that the busy-loop (goto again) will not invoke > caa_cpu_relax(), nor do adaptative waiting like > ___cds_wfcq_node_sync_next() normally does. Don't need, it will re-enter ___cds_wfcq_node_sync_next() to do it. > Also, it does not check for > blocking/non-blocking caller. we can add code to check it. but: for () { see src_q_head->node.next is not NULL xchg fail } Is this a kind of blocking? > Also, whenever possible, I like to have > for () or do/while constructs in place to make it clear that we can loop. > So a modification of your proposal would look like: > > /* Return 1 if nonblocking and needs to block, 0 otherwise */ > static inline > bool ___cds_wfcq_busy_wait(int *attempt, int blocking) > { > if (!blocking) > return 1; > if (+attempt >= WFCQ_ADAPT_ATTEMPTS) { > poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > attempt = 0; > } else { > caa_cpu_relax(); > } > return 0; > } > > [...] > > struct cds_wfcq_node *head, *tail; > int attempt = 0; > > for (;;) { > if (_cds_wfcq_empty(src_q_head, src_q_tail)) > return CDS_WFCQ_RET_SRC_EMPTY; > head = uatomic_xchg(&src_q_head->node.next, NULL); > if (head) > break; > if (___cds_wfcq_busy_wait(&attempt, blocking)) > return CDS_WFCQ_RET_WOULDBLOCK; return _cds_wfcq_empty(src_q_head, src_q_tail) ? CDS_WFCQ_RET_SRC_EMPTY : CDS_WFCQ_RET_WOULDBLOCK > } > > > Thoughts ? > > Thanks, > > Mathieu > > >> >>> >>> /* >>> * Memory barrier implied before uatomic_xchg() orders store to >>> @@ -435,14 +472,13 @@ ___cds_wfcq_splice( >>> return CDS_WFCQ_RET_DEST_EMPTY; >>> } >>> >>> - >>> /* >>> * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. >>> * >>> * Dequeue all nodes from src_q. >>> * dest_q must be already initialized. >>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured >>> - * by the caller. >>> + * Mutual exclusion for src_q should be ensured by the caller as >>> + * specified in the "Synchronisation table". >>> * Returns enum cds_wfcq_ret which indicates the state of the src or >>> * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. >>> */ >>> diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h >>> index ddf6b87..d9ec534 100644 >>> --- a/urcu/wfcqueue.h >>> +++ b/urcu/wfcqueue.h >>> @@ -46,7 +46,7 @@ extern "C" { >>> #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) >>> >>> enum cds_wfcq_ret { >>> - CDS_WFCQ_RET_WOULDBLOCK = -1, >>> + CDS_WFCQ_RET_WOULDBLOCK = -1, >>> CDS_WFCQ_RET_DEST_EMPTY = 0, >>> CDS_WFCQ_RET_DEST_NON_EMPTY = 1, >>> CDS_WFCQ_RET_SRC_EMPTY = 2, >>> @@ -110,13 +110,28 @@ struct cds_wfcq_tail { >>> /* >>> * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API >>> * >>> - * Unless otherwise stated, the caller must ensure mutual exclusion of >>> - * queue update operations "dequeue" and "splice" (for source queue). >>> - * Queue read operations "first" and "next", which are used by >>> - * "for_each" iterations, need to be protected against concurrent >>> - * "dequeue" and "splice" (for source queue) by the caller. >>> - * "enqueue", "splice" (for destination queue), and "empty" are the only >>> - * operations that can be used without any mutual exclusion. >>> + * Synchronization table: >>> + * >>> + * External synchronization techniques described in the API below is >>> + * required between pairs marked with "X". No external synchronization >>> + * required between pairs marked with "-". >>> + * >>> + * Legend: >>> + * [1] cds_wfcq_enqueue >>> + * [2] __cds_wfcq_splice (destination queue) >>> + * [3] __cds_wfcq_dequeue >>> + * [4] __cds_wfcq_splice (source queue) >>> + * [5] __cds_wfcq_first >>> + * [6] __cds_wfcq_next >>> + * >>> + * [1] [2] [3] [4] [5] [6] >>> + * [1] - - - - - - >>> + * [2] - - - - - - >>> + * [3] - - X X X X >>> + * [4] - - X - X X >>> + * [5] - - X X - - >>> + * [6] - - X X - - >>> + * >>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). >>> * >>> * For convenience, cds_wfcq_dequeue_blocking() and >>> @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( >>> * >>> * Dequeue all nodes from src_q. >>> * dest_q must be already initialized. >>> - * Content written into the node before enqueue is guaranteed to be >>> - * consistent, but no other memory ordering is ensured. >>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured >>> - * by the caller. >>> - * >>> + * Mutual exclusion for src_q should be ensured by the caller as >>> + * specified in the "Synchronisation table". >>> * Returns enum cds_wfcq_ret which indicates the state of the src or >>> - * dest queue. Cannot block. >>> + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. >>> */ >>> extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( >>> struct cds_wfcq_head *dest_q_head, >>> diff --git a/wfcqueue.c b/wfcqueue.c >>> index 207df95..ab0eb93 100644 >>> --- a/wfcqueue.c >>> +++ b/wfcqueue.c >>> @@ -1,7 +1,7 @@ >>> /* >>> * wfcqueue.c >>> * >>> - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue >>> + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue >>> * >>> * Copyright 2010-2012 - Mathieu Desnoyers >>> * Copyright 2011-2012 - Lai Jiangshan >> > From laijs at cn.fujitsu.com Thu Nov 22 04:04:47 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Thu, 22 Nov 2012 17:04:47 +0800 Subject: [lttng-dev] [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <20121121183304.GA25932@Krystal> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> <50AC8F56.6040109@cn.fujitsu.com> <20121121183304.GA25932@Krystal> Message-ID: <50ADEAAF.1010703@cn.fujitsu.com> On 11/22/2012 02:33 AM, Mathieu Desnoyers wrote: > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: >> Could you delay 14~16 for 40 days if I don't implement it in 40 days? > > I'm curious to know more about the changes you are planning. Is that > another way to implement grace periods that would allow multiple threads > to execute synchronize_rcu() concurrently ? synchronize_rcu()s in this implement share coarse-grain step(1 GP) to achieve concurrence. My implement will use fine-grain step(1 check or 1 flip) like SRCU. and call_rcu() is also considered in this implement to avoid unneeded wait. > > Please note that changes in these algorithms will need to go through > very strict review/validation/verification. So I expect that if it takes > 40 days to implement, we can plan at least 3-4 months of validation work. I means I don't have time. If I can't steal some time from the late 40 days, this code is OK for me. > > With that in mind, would it make sense to merge the batching approach in > the meantime ? The advantage of the batching approach is that it does > not touch the core of the synchronization algorithm. > > Thoughts ? > > Thanks, > > Mathieu > >> >> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: >>> Here are benchmarks on batching of synchronize_rcu(), and it leads to >>> very interesting scalability improvement and speedups, e.g., on a >>> 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater >>> threads, each updater using synchronize_rcu()): >>> >>> * Serialized grace periods : >>> >>> ./test_urcu_qsbr 4 20 20 >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 >>> rdur 0 wdur 0 nr_writers 20 wdelay 0 >>> nr_reads 20251412728 nr_writes 1826331 nr_ops 20253239059 >>> >>> * Batched grace periods : >>> >>> ./test_urcu_qsbr 4 20 20 >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 >>> rdur 0 wdur 0 nr_writers 20 wdelay 0 >>> nr_reads 15141994746 nr_writes 9382515 nr_ops 15151377261 >>> >>> For a 9382515/1826331 = 5.13 speedup for 20 updaters. >>> >>> Of course, we can see that readers have slowed down, probably due to >>> increased update traffic, given there is no change to the read-side code >>> whatsoever. >>> >>> Now let's see the penality of managing the stack for single-updater. >>> With 4 readers, single updater: >>> >>> * Serialized grace periods : >>> >>> ./test_urcu_qsbr 4 1 20 >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 >>> rdur 0 wdur 0 nr_writers 1 wdelay 0 >>> nr_reads 19240784755 nr_writes 2130839 nr_ops 19242915594 >>> >>> * Batched grace periods : >>> >>> ./test_urcu_qsbr 4 1 20 >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 >>> rdur 0 wdur 0 nr_writers 1 wdelay 0 >>> nr_reads 19160162768 nr_writes 2253068 nr_ops 1916241583 >>> >>> 2253068 vs 2137036 -> a couple of runs show that this difference lost in >>> the noise for single updater. >>> >>> CC: Paul E. McKenney >>> CC: Lai Jiangshan >>> CC: Alan Stern >>> Signed-off-by: Mathieu Desnoyers >>> --- >>> urcu-qsbr.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 151 insertions(+) >>> >>> diff --git a/urcu-qsbr.c b/urcu-qsbr.c >>> index 5b341b5..7f747ed 100644 >>> --- a/urcu-qsbr.c >>> +++ b/urcu-qsbr.c >>> @@ -36,6 +36,7 @@ >>> #include >>> >>> #include "urcu/wfcqueue.h" >>> +#include "urcu/wfstack.h" >>> #include "urcu/map/urcu-qsbr.h" >>> #define BUILD_QSBR_LIB >>> #include "urcu/static/urcu-qsbr.h" >>> @@ -78,6 +79,35 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); >>> >>> static CDS_LIST_HEAD(registry); >>> >>> +/* >>> + * Number of busy-loop attempts before waiting on futex for grace period >>> + * batching. >>> + */ >>> +#define RCU_AWAKE_ATTEMPTS 1000 >>> + >>> +enum adapt_wakeup_state { >>> + /* AWAKE_WAITING is compared directly (futex compares it). */ >>> + AWAKE_WAITING = 0, >>> + /* non-zero are used as masks. */ >>> + AWAKE_WAKEUP = (1 << 0), >>> + AWAKE_AWAKENED = (1 << 1), >>> + AWAKE_TEARDOWN = (1 << 2), >>> +}; >>> + >>> +struct gp_waiters_thread { >>> + struct cds_wfs_node node; >>> + int32_t wait_futex; >>> +}; >>> + >>> +/* >>> + * Stack keeping threads awaiting to wait for a grace period. Contains >>> + * struct gp_waiters_thread objects. >>> + */ >>> +static struct cds_wfs_stack gp_waiters = { >>> + .head = CDS_WFS_END, >>> + .lock = PTHREAD_MUTEX_INITIALIZER, >>> +}; >>> + >>> static void mutex_lock(pthread_mutex_t *mutex) >>> { >>> int ret; >>> @@ -116,6 +146,58 @@ static void wait_gp(void) >>> NULL, NULL, 0); >>> } >>> >>> +/* >>> + * Note: urcu_adaptative_wake_up needs "value" to stay allocated >>> + * throughout its execution. In this scheme, the waiter owns the futex >>> + * memory, and we only allow it to free this memory when it receives the >>> + * AWAKE_TEARDOWN flag. >>> + */ >>> +static void urcu_adaptative_wake_up(int32_t *value) >>> +{ >>> + cmm_smp_mb(); >>> + assert(uatomic_read(value) == AWAKE_WAITING); >>> + uatomic_set(value, AWAKE_WAKEUP); >>> + if (!(uatomic_read(value) & AWAKE_AWAKENED)) >>> + futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); >>> + /* Allow teardown of "value" memory. */ >>> + uatomic_or(value, AWAKE_TEARDOWN); >>> +} >>> + >>> +/* >>> + * Caller must initialize "value" to AWAKE_WAITING before passing its >>> + * memory to waker thread. >>> + */ >>> +static void urcu_adaptative_busy_wait(int32_t *value) >>> +{ >>> + unsigned int i; >>> + >>> + /* Load and test condition before read futex */ >>> + cmm_smp_rmb(); >>> + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { >>> + if (uatomic_read(value) != AWAKE_WAITING) >>> + goto skip_futex_wait; >>> + caa_cpu_relax(); >>> + } >>> + futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); >>> +skip_futex_wait: >>> + >>> + /* Tell waker thread than we are awakened. */ >>> + uatomic_or(value, AWAKE_AWAKENED); >>> + >>> + /* >>> + * Wait until waker thread lets us know it's ok to tear down >>> + * memory allocated for value. >>> + */ >>> + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { >>> + if (uatomic_read(value) & AWAKE_TEARDOWN) >>> + break; >>> + caa_cpu_relax(); >>> + } >>> + while (!(uatomic_read(value) & AWAKE_TEARDOWN)) >>> + poll(NULL, 0, 10); >>> + assert(uatomic_read(value) & AWAKE_TEARDOWN); >>> +} >>> + >>> static void wait_for_readers(struct cds_list_head *input_readers, >>> struct cds_list_head *cur_snap_readers, >>> struct cds_list_head *qsreaders) >>> @@ -198,6 +280,9 @@ void synchronize_rcu(void) >>> CDS_LIST_HEAD(cur_snap_readers); >>> CDS_LIST_HEAD(qsreaders); >>> unsigned long was_online; >>> + struct gp_waiters_thread gp_waiters_thread; >>> + struct cds_wfs_head *gp_waiters_head; >>> + struct cds_wfs_node *waiters_iter, *waiters_iter_n; >>> >>> was_online = URCU_TLS(rcu_reader).ctr; >>> >>> @@ -214,8 +299,26 @@ void synchronize_rcu(void) >>> else >>> cmm_smp_mb(); >>> >>> + /* >>> + * Add ourself to gp_waiters stack of threads awaiting to wait >>> + * for a grace period. Proceed to perform the grace period only >>> + * if we are the first thread added into the stack. >>> + */ >>> + cds_wfs_node_init(&gp_waiters_thread.node); >>> + gp_waiters_thread.wait_futex = AWAKE_WAITING; >>> + if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { >>> + /* Not first in stack: will be awakened by another thread. */ >>> + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); >>> + goto gp_end; >>> + } >>> + >>> mutex_lock(&rcu_gp_lock); >>> >>> + /* >>> + * Pop all waiters into our local stack head. >>> + */ >>> + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); >>> + >>> if (cds_list_empty(®istry)) >>> goto out; >>> >>> @@ -272,6 +375,19 @@ void synchronize_rcu(void) >>> out: >>> mutex_unlock(&rcu_gp_lock); >>> >>> + /* Wake all waiters in our stack head, excluding ourself. */ >>> + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, >>> + waiters_iter_n) { >>> + struct gp_waiters_thread *wt; >>> + >>> + wt = caa_container_of(waiters_iter, >>> + struct gp_waiters_thread, node); >>> + if (wt == &gp_waiters_thread) >>> + continue; >>> + urcu_adaptative_wake_up(&wt->wait_futex); >>> + } >>> + >>> +gp_end: >>> /* >>> * Finish waiting for reader threads before letting the old ptr being >>> * freed. >>> @@ -286,6 +402,9 @@ void synchronize_rcu(void) >>> { >>> CDS_LIST_HEAD(qsreaders); >>> unsigned long was_online; >>> + struct gp_waiters_thread gp_waiters_thread; >>> + struct cds_wfs_head *gp_waiters_head; >>> + struct cds_wfs_node *waiters_iter, *waiters_iter_n; >>> >>> was_online = URCU_TLS(rcu_reader).ctr; >>> >>> @@ -299,7 +418,26 @@ void synchronize_rcu(void) >>> else >>> cmm_smp_mb(); >>> >>> + /* >>> + * Add ourself to gp_waiters stack of threads awaiting to wait >>> + * for a grace period. Proceed to perform the grace period only >>> + * if we are the first thread added into the stack. >>> + */ >>> + cds_wfs_node_init(&gp_waiters_thread.node); >>> + gp_waiters_thread.wait_futex = AWAKE_WAITING; >>> + if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { >>> + /* Not first in stack: will be awakened by another thread. */ >>> + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); >>> + goto gp_end; >>> + } >>> + >>> mutex_lock(&rcu_gp_lock); >>> + >>> + /* >>> + * Pop all waiters into our local stack head. >>> + */ >>> + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); >>> + >>> if (cds_list_empty(®istry)) >>> goto out; >>> >>> @@ -334,6 +472,19 @@ void synchronize_rcu(void) >>> out: >>> mutex_unlock(&rcu_gp_lock); >>> >>> + /* Wake all waiters in our stack head, excluding ourself. */ >>> + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, >>> + waiters_iter_n) { >>> + struct gp_waiters_thread *wt; >>> + >>> + wt = caa_container_of(waiters_iter, >>> + struct gp_waiters_thread, node); >>> + if (wt == &gp_waiters_thread) >>> + continue; >>> + urcu_adaptative_wake_up(&wt->wait_futex); >>> + } >>> + >>> +gp_end: >>> if (was_online) >>> rcu_thread_online(); >>> else >> > From Paul_Woegerer at mentor.com Thu Nov 22 09:08:40 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Thu, 22 Nov 2012 15:08:40 +0100 Subject: [lttng-dev] Emitting events from shared object constructors is (currently) not possible Message-ID: <50AE31E8.4040507@mentor.com> I recently stumbled over the following lttng-ust limitation: I tried to emit events from a shared objects constructor function: __attribute__((constructor)) void func_constructor() { tracepoint( foo, bar ); } Unfortunately this doesn't work because the constructor functions of LTTng itself (__tracepoints__init and the ones from ust-tracepoint-event.h) are not yet run. Trying to solve this problem with explicit constructor priority on my side alone doesn't work: __attribute__((constructor (1111))) void func_constructor() { tracepoint( foo, bar ); } That's because whatever I specify as priority is irrelevant. LTTng's constructors without priority will always come last. After also adding priority to the lttng constructor I was able to make it work (see patch below): diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index 8b08914..532f1d2 100644 --- a/include/lttng/tracepoint.h +++ b/include/lttng/tracepoint.h @@ -261,7 +261,7 @@ int __tracepoint_registered struct tracepoint_dlopen tracepoint_dlopen __attribute__((weak, visibility("hidden"))); -static void lttng_ust_notrace __attribute__((constructor)) +static void lttng_ust_notrace __attribute__((constructor (1000))) __tracepoints__init(void); static void __tracepoints__init(void) @@ -300,7 +300,7 @@ __tracepoints__init(void) __start___tracepoints_ptrs); } -static void lttng_ust_notrace __attribute__((destructor)) +static void lttng_ust_notrace __attribute__((destructor (1000))) __tracepoints__destroy(void); static void __tracepoints__destroy(void) diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index 74d06e1..7ad3144 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -638,7 +638,7 @@ static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PR /* Reset all macros within TRACEPOINT_EVENT */ #include -static void lttng_ust_notrace __attribute__((constructor)) +static void lttng_ust_notrace __attribute__((constructor (1000))) _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void); static void _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) @@ -649,7 +649,7 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) assert(!ret); } -static void lttng_ust_notrace __attribute__((destructor)) +static void lttng_ust_notrace __attribute__((destructor (1000))) _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void); static void _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From mathieu.desnoyers at efficios.com Thu Nov 22 10:39:01 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 22 Nov 2012 10:39:01 -0500 Subject: [lttng-dev] Emitting events from shared object constructors is (currently) not possible In-Reply-To: <50AE31E8.4040507@mentor.com> References: <50AE31E8.4040507@mentor.com> Message-ID: <20121122153901.GA14685@Krystal> * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > I recently stumbled over the following lttng-ust limitation: > > I tried to emit events from a shared objects constructor function: > > __attribute__((constructor)) > void func_constructor() > { > tracepoint( foo, bar ); > } > > Unfortunately this doesn't work because the constructor functions of > LTTng itself (__tracepoints__init and the ones from > ust-tracepoint-event.h) are not yet run. > > Trying to solve this problem with explicit constructor priority on my > side alone doesn't work: > > __attribute__((constructor (1111))) > void func_constructor() > { > tracepoint( foo, bar ); > } > > That's because whatever I specify as priority is irrelevant. LTTng's > constructors without priority will always come last. > > After also adding priority to the lttng constructor I was able to make > it work (see patch below): Hi Paul, I notice that you probably embed your probes along with your code within the same shared object/executable, right ? Unfortunately, this approach does not work if the probes are placed in a different shared object than the program code. Here is an example: a.c: #include __attribute__((constructor(998))) void fcta_prio1(void) { fprintf(stderr, "fcta prio 998\n"); } __attribute__((constructor)) void fcta(void) { fprintf(stderr, "fcta\n"); } __attribute__((constructor(1000))) void fcta_prio2(void) { fprintf(stderr, "fcta prio 1000\n"); } b.c: #include __attribute__((constructor(999))) void fctb_prio1(void) { fprintf(stderr, "fctb prio 999\n"); } __attribute__((constructor)) void fctb(void) { fprintf(stderr, "fctb\n"); } __attribute__((constructor(1001))) void fctb_prio2(void) { fprintf(stderr, "fctb prio 1001\n"); } main.c: int main() { return 0; } Makefile: all: gcc -fPIC -shared -Wl,-soname,liba.so -o liba.so a.c gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.c gcc -o test main.c -L./ -la -lb exec with: LD_LIBRARY_PATH=. ./test result: fctb prio 999 fctb prio 1001 fctb fcta prio 998 fcta prio 1000 fcta If we build test2 all within the same executable, then the order is fine: gcc -o test2 main.c a.c b.c ./test2 result: fcta prio 998 fctb prio 999 fcta prio 1000 fctb prio 1001 fcta fctb As we can notice, the priority is effective within a shared object, but has no ordering effect across .so. And having probes in separate .so is a very typical use case. One way we could envision allowing tracing of constructors in applications is to ensure __tracepoints__init, which always resides within the same object as the traced application code, runs with a high constructor priorita -- low value -- (for code compiled by compilers supporting this feature), and allow the application to invoke the probe constructor early. So the proposed changes would be: 1 - add a constructor priority for __tracepoints__init/__tracepoints_destroy in tracepoint.h. Use macros to test for gcc version which allow this attribute. 2 - add some API that could let user code call __lttng_events_init__PROVIDER_NAME explicitly. Add an "already executed" flag to guard __lttng_events_init__PROVIDER_NAME. This API should still allow to LD_PRELOAD the probes (no dependency on the probe symbols, possibly by using dlsym ?) 3 - make lttng_probe_register call lttng_ust_init needed. Add an "already executed" flag to guard lttng_ust_init. Thoughts ? Thanks, Mathieu > > diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h > index 8b08914..532f1d2 100644 > --- a/include/lttng/tracepoint.h > +++ b/include/lttng/tracepoint.h > @@ -261,7 +261,7 @@ int __tracepoint_registered > struct tracepoint_dlopen tracepoint_dlopen > __attribute__((weak, visibility("hidden"))); > > -static void lttng_ust_notrace __attribute__((constructor)) > +static void lttng_ust_notrace __attribute__((constructor (1000))) > __tracepoints__init(void); > static void > __tracepoints__init(void) > @@ -300,7 +300,7 @@ __tracepoints__init(void) > __start___tracepoints_ptrs); > } > > -static void lttng_ust_notrace __attribute__((destructor)) > +static void lttng_ust_notrace __attribute__((destructor (1000))) > __tracepoints__destroy(void); > static void > __tracepoints__destroy(void) > diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h > index 74d06e1..7ad3144 100644 > --- a/include/lttng/ust-tracepoint-event.h > +++ b/include/lttng/ust-tracepoint-event.h > @@ -638,7 +638,7 @@ static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PR > > /* Reset all macros within TRACEPOINT_EVENT */ > #include > -static void lttng_ust_notrace __attribute__((constructor)) > +static void lttng_ust_notrace __attribute__((constructor (1000))) > _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void); > static void > _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) > @@ -649,7 +649,7 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) > assert(!ret); > } > > -static void lttng_ust_notrace __attribute__((destructor)) > +static void lttng_ust_notrace __attribute__((destructor (1000))) > _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void); > static void > _TP_COMBINE_TOKENS(__lttng_events_exit__, TRACEPOINT_PROVIDER)(void) > > > > -- > Paul Woegerer | SW Development Engineer > http://go.mentor.com/sourceryanalyzer > > Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria > Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS > > Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. > Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From Paul_Woegerer at mentor.com Thu Nov 22 11:03:59 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Thu, 22 Nov 2012 17:03:59 +0100 Subject: [lttng-dev] Emitting events from shared object constructors is (currently) not possible In-Reply-To: <20121122153901.GA14685@Krystal> References: <50AE31E8.4040507@mentor.com> <20121122153901.GA14685@Krystal> Message-ID: <50AE4CEF.9050809@mentor.com> On 11/22/2012 04:39 PM, Mathieu Desnoyers wrote: > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: >> I recently stumbled over the following lttng-ust limitation: >> >> I tried to emit events from a shared objects constructor function: >> >> __attribute__((constructor)) >> void func_constructor() >> { >> tracepoint( foo, bar ); >> } >> >> Unfortunately this doesn't work because the constructor functions of >> LTTng itself (__tracepoints__init and the ones from >> ust-tracepoint-event.h) are not yet run. >> >> Trying to solve this problem with explicit constructor priority on my >> side alone doesn't work: >> >> __attribute__((constructor (1111))) >> void func_constructor() >> { >> tracepoint( foo, bar ); >> } >> >> That's because whatever I specify as priority is irrelevant. LTTng's >> constructors without priority will always come last. >> >> After also adding priority to the lttng constructor I was able to make >> it work (see patch below): > > Hi Paul, > > I notice that you probably embed your probes along with your code within > the same shared object/executable, right ? > > Unfortunately, this approach does not work if the probes are placed in a > different shared object than the program code. Here is an example: Hi Mathieu, In case the probes would be defined in different shared object from the one where they are used we wouldn't have a problem at all because the dynamic linker would invoke all the constructor functions for the probe shared object before the constructor functions of the shared object that has a dependency to the probe shared object, right ? And even if this is not the case I could explicitly dlopen the probe shared object from within my constructor function and thus make sure that the constructor function of the probe shared object gets called before I emit an event from my constructor function. -- Paul -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From mathieu.desnoyers at efficios.com Thu Nov 22 11:45:12 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 22 Nov 2012 11:45:12 -0500 Subject: [lttng-dev] Emitting events from shared object constructors is (currently) not possible In-Reply-To: <50AE4CEF.9050809@mentor.com> References: <50AE31E8.4040507@mentor.com> <20121122153901.GA14685@Krystal> <50AE4CEF.9050809@mentor.com> Message-ID: <20121122164512.GA16119@Krystal> * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > On 11/22/2012 04:39 PM, Mathieu Desnoyers wrote: > > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: > >> I recently stumbled over the following lttng-ust limitation: > >> > >> I tried to emit events from a shared objects constructor function: > >> > >> __attribute__((constructor)) > >> void func_constructor() > >> { > >> tracepoint( foo, bar ); > >> } > >> > >> Unfortunately this doesn't work because the constructor functions of > >> LTTng itself (__tracepoints__init and the ones from > >> ust-tracepoint-event.h) are not yet run. > >> > >> Trying to solve this problem with explicit constructor priority on my > >> side alone doesn't work: > >> > >> __attribute__((constructor (1111))) > >> void func_constructor() > >> { > >> tracepoint( foo, bar ); > >> } > >> > >> That's because whatever I specify as priority is irrelevant. LTTng's > >> constructors without priority will always come last. > >> > >> After also adding priority to the lttng constructor I was able to make > >> it work (see patch below): > > > > Hi Paul, > > > > I notice that you probably embed your probes along with your code within > > the same shared object/executable, right ? > > > > Unfortunately, this approach does not work if the probes are placed in a > > different shared object than the program code. Here is an example: > > Hi Mathieu, > > In case the probes would be defined in different shared object from the > one where they are used we wouldn't have a problem at all because the > dynamic linker would invoke all the constructor functions for the probe > shared object before the constructor functions of the shared object that > has a dependency to the probe shared object, right ? The instrumented code does not have dependency on the probe shared object, so we can ship applications separately from their probe .so. So unfortunately, the linker is not doing this for us. > > And even if this is not the case I could explicitly dlopen the probe > shared object from within my constructor function and thus make sure > that the constructor function of the probe shared object gets called > before I emit an event from my constructor function. The idea would be to provide a nice API to facilitate this use-case, and document it in the instrumentation guide-lines (lttng-ust(3)). Thanks, Mathieu > > -- > Paul > > -- > Paul Woegerer | SW Development Engineer > http://go.mentor.com/sourceryanalyzer > > Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria > Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS > > Android is a trademark of Google Inc. Use of this trademark is subject > to Google Permissions. > Linux is the registered trademark of Linus Torvalds in the U.S. and > other countries. -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From paulmck at linux.vnet.ibm.com Thu Nov 22 13:30:41 2012 From: paulmck at linux.vnet.ibm.com (Paul E. McKenney) Date: Thu, 22 Nov 2012 10:30:41 -0800 Subject: [lttng-dev] [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <50ADEAAF.1010703@cn.fujitsu.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> <50AC8F56.6040109@cn.fujitsu.com> <20121121183304.GA25932@Krystal> <50ADEAAF.1010703@cn.fujitsu.com> Message-ID: <20121122183041.GB2829@linux.vnet.ibm.com> On Thu, Nov 22, 2012 at 05:04:47PM +0800, Lai Jiangshan wrote: > On 11/22/2012 02:33 AM, Mathieu Desnoyers wrote: > > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > >> Could you delay 14~16 for 40 days if I don't implement it in 40 days? > > > > I'm curious to know more about the changes you are planning. Is that > > another way to implement grace periods that would allow multiple threads > > to execute synchronize_rcu() concurrently ? > > synchronize_rcu()s in this implement share coarse-grain step(1 GP) > to achieve concurrence. My implement will use fine-grain step(1 check or 1 flip) > like SRCU. and call_rcu() is also considered in this implement to avoid > unneeded wait. > > > > > Please note that changes in these algorithms will need to go through > > very strict review/validation/verification. So I expect that if it takes > > 40 days to implement, we can plan at least 3-4 months of validation work. > > I means I don't have time. If I can't steal some time from the late 40 days, > this code is OK for me. Why don't we take the current code, which would allow some academic projects to test on large systems in the next few months, and then replace it with your code when available and if appropriate? Thanx, Paul > > With that in mind, would it make sense to merge the batching approach in > > the meantime ? The advantage of the batching approach is that it does > > not touch the core of the synchronization algorithm. > > > > Thoughts ? > > > > Thanks, > > > > Mathieu > > > >> > >> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > >>> Here are benchmarks on batching of synchronize_rcu(), and it leads to > >>> very interesting scalability improvement and speedups, e.g., on a > >>> 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > >>> threads, each updater using synchronize_rcu()): > >>> > >>> * Serialized grace periods : > >>> > >>> ./test_urcu_qsbr 4 20 20 > >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > >>> rdur 0 wdur 0 nr_writers 20 wdelay 0 > >>> nr_reads 20251412728 nr_writes 1826331 nr_ops 20253239059 > >>> > >>> * Batched grace periods : > >>> > >>> ./test_urcu_qsbr 4 20 20 > >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > >>> rdur 0 wdur 0 nr_writers 20 wdelay 0 > >>> nr_reads 15141994746 nr_writes 9382515 nr_ops 15151377261 > >>> > >>> For a 9382515/1826331 = 5.13 speedup for 20 updaters. > >>> > >>> Of course, we can see that readers have slowed down, probably due to > >>> increased update traffic, given there is no change to the read-side code > >>> whatsoever. > >>> > >>> Now let's see the penality of managing the stack for single-updater. > >>> With 4 readers, single updater: > >>> > >>> * Serialized grace periods : > >>> > >>> ./test_urcu_qsbr 4 1 20 > >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > >>> rdur 0 wdur 0 nr_writers 1 wdelay 0 > >>> nr_reads 19240784755 nr_writes 2130839 nr_ops 19242915594 > >>> > >>> * Batched grace periods : > >>> > >>> ./test_urcu_qsbr 4 1 20 > >>> SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 > >>> rdur 0 wdur 0 nr_writers 1 wdelay 0 > >>> nr_reads 19160162768 nr_writes 2253068 nr_ops 1916241583 > >>> > >>> 2253068 vs 2137036 -> a couple of runs show that this difference lost in > >>> the noise for single updater. > >>> > >>> CC: Paul E. McKenney > >>> CC: Lai Jiangshan > >>> CC: Alan Stern > >>> Signed-off-by: Mathieu Desnoyers > >>> --- > >>> urcu-qsbr.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > >>> 1 file changed, 151 insertions(+) > >>> > >>> diff --git a/urcu-qsbr.c b/urcu-qsbr.c > >>> index 5b341b5..7f747ed 100644 > >>> --- a/urcu-qsbr.c > >>> +++ b/urcu-qsbr.c > >>> @@ -36,6 +36,7 @@ > >>> #include > >>> > >>> #include "urcu/wfcqueue.h" > >>> +#include "urcu/wfstack.h" > >>> #include "urcu/map/urcu-qsbr.h" > >>> #define BUILD_QSBR_LIB > >>> #include "urcu/static/urcu-qsbr.h" > >>> @@ -78,6 +79,35 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > >>> > >>> static CDS_LIST_HEAD(registry); > >>> > >>> +/* > >>> + * Number of busy-loop attempts before waiting on futex for grace period > >>> + * batching. > >>> + */ > >>> +#define RCU_AWAKE_ATTEMPTS 1000 > >>> + > >>> +enum adapt_wakeup_state { > >>> + /* AWAKE_WAITING is compared directly (futex compares it). */ > >>> + AWAKE_WAITING = 0, > >>> + /* non-zero are used as masks. */ > >>> + AWAKE_WAKEUP = (1 << 0), > >>> + AWAKE_AWAKENED = (1 << 1), > >>> + AWAKE_TEARDOWN = (1 << 2), > >>> +}; > >>> + > >>> +struct gp_waiters_thread { > >>> + struct cds_wfs_node node; > >>> + int32_t wait_futex; > >>> +}; > >>> + > >>> +/* > >>> + * Stack keeping threads awaiting to wait for a grace period. Contains > >>> + * struct gp_waiters_thread objects. > >>> + */ > >>> +static struct cds_wfs_stack gp_waiters = { > >>> + .head = CDS_WFS_END, > >>> + .lock = PTHREAD_MUTEX_INITIALIZER, > >>> +}; > >>> + > >>> static void mutex_lock(pthread_mutex_t *mutex) > >>> { > >>> int ret; > >>> @@ -116,6 +146,58 @@ static void wait_gp(void) > >>> NULL, NULL, 0); > >>> } > >>> > >>> +/* > >>> + * Note: urcu_adaptative_wake_up needs "value" to stay allocated > >>> + * throughout its execution. In this scheme, the waiter owns the futex > >>> + * memory, and we only allow it to free this memory when it receives the > >>> + * AWAKE_TEARDOWN flag. > >>> + */ > >>> +static void urcu_adaptative_wake_up(int32_t *value) > >>> +{ > >>> + cmm_smp_mb(); > >>> + assert(uatomic_read(value) == AWAKE_WAITING); > >>> + uatomic_set(value, AWAKE_WAKEUP); > >>> + if (!(uatomic_read(value) & AWAKE_AWAKENED)) > >>> + futex_noasync(value, FUTEX_WAKE, 1, NULL, NULL, 0); > >>> + /* Allow teardown of "value" memory. */ > >>> + uatomic_or(value, AWAKE_TEARDOWN); > >>> +} > >>> + > >>> +/* > >>> + * Caller must initialize "value" to AWAKE_WAITING before passing its > >>> + * memory to waker thread. > >>> + */ > >>> +static void urcu_adaptative_busy_wait(int32_t *value) > >>> +{ > >>> + unsigned int i; > >>> + > >>> + /* Load and test condition before read futex */ > >>> + cmm_smp_rmb(); > >>> + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { > >>> + if (uatomic_read(value) != AWAKE_WAITING) > >>> + goto skip_futex_wait; > >>> + caa_cpu_relax(); > >>> + } > >>> + futex_noasync(value, FUTEX_WAIT, AWAKE_WAITING, NULL, NULL, 0); > >>> +skip_futex_wait: > >>> + > >>> + /* Tell waker thread than we are awakened. */ > >>> + uatomic_or(value, AWAKE_AWAKENED); > >>> + > >>> + /* > >>> + * Wait until waker thread lets us know it's ok to tear down > >>> + * memory allocated for value. > >>> + */ > >>> + for (i = 0; i < RCU_AWAKE_ATTEMPTS; i++) { > >>> + if (uatomic_read(value) & AWAKE_TEARDOWN) > >>> + break; > >>> + caa_cpu_relax(); > >>> + } > >>> + while (!(uatomic_read(value) & AWAKE_TEARDOWN)) > >>> + poll(NULL, 0, 10); > >>> + assert(uatomic_read(value) & AWAKE_TEARDOWN); > >>> +} > >>> + > >>> static void wait_for_readers(struct cds_list_head *input_readers, > >>> struct cds_list_head *cur_snap_readers, > >>> struct cds_list_head *qsreaders) > >>> @@ -198,6 +280,9 @@ void synchronize_rcu(void) > >>> CDS_LIST_HEAD(cur_snap_readers); > >>> CDS_LIST_HEAD(qsreaders); > >>> unsigned long was_online; > >>> + struct gp_waiters_thread gp_waiters_thread; > >>> + struct cds_wfs_head *gp_waiters_head; > >>> + struct cds_wfs_node *waiters_iter, *waiters_iter_n; > >>> > >>> was_online = URCU_TLS(rcu_reader).ctr; > >>> > >>> @@ -214,8 +299,26 @@ void synchronize_rcu(void) > >>> else > >>> cmm_smp_mb(); > >>> > >>> + /* > >>> + * Add ourself to gp_waiters stack of threads awaiting to wait > >>> + * for a grace period. Proceed to perform the grace period only > >>> + * if we are the first thread added into the stack. > >>> + */ > >>> + cds_wfs_node_init(&gp_waiters_thread.node); > >>> + gp_waiters_thread.wait_futex = AWAKE_WAITING; > >>> + if (cds_wfs_push(&gp_waiters, &gp_waiters_node) != 0) { > >>> + /* Not first in stack: will be awakened by another thread. */ > >>> + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); > >>> + goto gp_end; > >>> + } > >>> + > >>> mutex_lock(&rcu_gp_lock); > >>> > >>> + /* > >>> + * Pop all waiters into our local stack head. > >>> + */ > >>> + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); > >>> + > >>> if (cds_list_empty(®istry)) > >>> goto out; > >>> > >>> @@ -272,6 +375,19 @@ void synchronize_rcu(void) > >>> out: > >>> mutex_unlock(&rcu_gp_lock); > >>> > >>> + /* Wake all waiters in our stack head, excluding ourself. */ > >>> + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, > >>> + waiters_iter_n) { > >>> + struct gp_waiters_thread *wt; > >>> + > >>> + wt = caa_container_of(waiters_iter, > >>> + struct gp_waiters_thread, node); > >>> + if (wt == &gp_waiters_thread) > >>> + continue; > >>> + urcu_adaptative_wake_up(&wt->wait_futex); > >>> + } > >>> + > >>> +gp_end: > >>> /* > >>> * Finish waiting for reader threads before letting the old ptr being > >>> * freed. > >>> @@ -286,6 +402,9 @@ void synchronize_rcu(void) > >>> { > >>> CDS_LIST_HEAD(qsreaders); > >>> unsigned long was_online; > >>> + struct gp_waiters_thread gp_waiters_thread; > >>> + struct cds_wfs_head *gp_waiters_head; > >>> + struct cds_wfs_node *waiters_iter, *waiters_iter_n; > >>> > >>> was_online = URCU_TLS(rcu_reader).ctr; > >>> > >>> @@ -299,7 +418,26 @@ void synchronize_rcu(void) > >>> else > >>> cmm_smp_mb(); > >>> > >>> + /* > >>> + * Add ourself to gp_waiters stack of threads awaiting to wait > >>> + * for a grace period. Proceed to perform the grace period only > >>> + * if we are the first thread added into the stack. > >>> + */ > >>> + cds_wfs_node_init(&gp_waiters_thread.node); > >>> + gp_waiters_thread.wait_futex = AWAKE_WAITING; > >>> + if (cds_wfs_push(&gp_waiters, &gp_waiters_thread.node) != 0) { > >>> + /* Not first in stack: will be awakened by another thread. */ > >>> + urcu_adaptative_busy_wait(&gp_waiters_thread.wait_futex); > >>> + goto gp_end; > >>> + } > >>> + > >>> mutex_lock(&rcu_gp_lock); > >>> + > >>> + /* > >>> + * Pop all waiters into our local stack head. > >>> + */ > >>> + gp_waiters_head = __cds_wfs_pop_all(&gp_waiters); > >>> + > >>> if (cds_list_empty(®istry)) > >>> goto out; > >>> > >>> @@ -334,6 +472,19 @@ void synchronize_rcu(void) > >>> out: > >>> mutex_unlock(&rcu_gp_lock); > >>> > >>> + /* Wake all waiters in our stack head, excluding ourself. */ > >>> + cds_wfs_for_each_blocking_safe(gp_waiters_head, waiters_iter, > >>> + waiters_iter_n) { > >>> + struct gp_waiters_thread *wt; > >>> + > >>> + wt = caa_container_of(waiters_iter, > >>> + struct gp_waiters_thread, node); > >>> + if (wt == &gp_waiters_thread) > >>> + continue; > >>> + urcu_adaptative_wake_up(&wt->wait_futex); > >>> + } > >>> + > >>> +gp_end: > >>> if (was_online) > >>> rcu_thread_online(); > >>> else > >> > > > From mathieu.desnoyers at efficios.com Thu Nov 22 13:54:55 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 22 Nov 2012 13:54:55 -0500 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <50ADE76F.7090006@cn.fujitsu.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> <50AC93E0.1050204@cn.fujitsu.com> <20121121151823.GB21518@Krystal> <50ADE76F.7090006@cn.fujitsu.com> Message-ID: <20121122185455.GA17756@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > On 11/21/2012 11:18 PM, Mathieu Desnoyers wrote: > > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > >> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > >>> A carefully crafted splice operation does not need to use an external > >>> mutex to synchronize against other splice operations. > >>> > >>> The trick is atomically exchange the head next pointer with > >>> NULL. If the pointer we replaced was NULL, it means the queue was > >>> possibly empty. If head next was not NULL, by setting head to NULL, we > >>> ensure that concurrent splice operations are going to see an empty > >>> queue, even if concurrent enqueue operations move tail further. This > >>> means that as long as we are within splice, after setting head to NULL, > >>> but before moving tail back to head, concurrent splice operations will > >>> always see an empty queue, therefore acting as mutual exclusion. > >>> > >>> If exchange returns a NULL head, we confirm that it was indeed empty by > >>> checking if the tail pointer points to the head node, busy-waiting if > >>> necessary. > >>> > >>> Then the last step is to move the tail pointer to head. At that point, > >>> enqueuers are going to start enqueuing at head again, and other splice > >>> operations will be able to proceed. > >>> > >>> Signed-off-by: Mathieu Desnoyers > >>> --- > >>> urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ > >>> urcu/wfcqueue.h | 40 ++++++++++++++++++---------- > >>> wfcqueue.c | 2 +- > >>> 3 files changed, 79 insertions(+), 31 deletions(-) > >>> > >>> diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > >>> index 8774c03..4b2de50 100644 > >>> --- a/urcu/static/wfcqueue.h > >>> +++ b/urcu/static/wfcqueue.h > >>> @@ -46,15 +46,30 @@ extern "C" { > >>> * half-wait-free/half-blocking queue implementation done by Paul E. > >>> * McKenney. > >>> * > >>> - * Mutual exclusion of __cds_wfcq_* API > >>> - * > >>> - * Unless otherwise stated, the caller must ensure mutual exclusion of > >>> - * queue update operations "dequeue" and "splice" (for source queue). > >>> - * Queue read operations "first" and "next", which are used by > >>> - * "for_each" iterations, need to be protected against concurrent > >>> - * "dequeue" and "splice" (for source queue) by the caller. > >>> - * "enqueue", "splice" (for destination queue), and "empty" are the only > >>> - * operations that can be used without any mutual exclusion. > >>> + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > >>> + * > >>> + * Synchronization table: > >>> + * > >>> + * External synchronization techniques described in the API below is > >>> + * required between pairs marked with "X". No external synchronization > >>> + * required between pairs marked with "-". > >>> + * > >>> + * Legend: > >>> + * [1] cds_wfcq_enqueue > >>> + * [2] __cds_wfcq_splice (destination queue) > >>> + * [3] __cds_wfcq_dequeue > >>> + * [4] __cds_wfcq_splice (source queue) > >>> + * [5] __cds_wfcq_first > >>> + * [6] __cds_wfcq_next > >>> + * > >>> + * [1] [2] [3] [4] [5] [6] > >>> + * [1] - - - - - - > >>> + * [2] - - - - - - > >>> + * [3] - - X X X X > >>> + * [4] - - X - X X > >>> + * [5] - - X X - - > >>> + * [6] - - X X - - > >>> + * > >>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > >>> * > >>> * For convenience, cds_wfcq_dequeue_blocking() and > >>> @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, > >>> return ___cds_wfcq_dequeue(head, tail, 0); > >>> } > >>> > >>> +/* > >>> + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. > >>> + * > >>> + * Dequeue all nodes from src_q. > >>> + * dest_q must be already initialized. > >>> + * Mutual exclusion for src_q should be ensured by the caller as > >>> + * specified in the "Synchronisation table". > >>> + * Returns enum cds_wfcq_ret which indicates the state of the src or > >>> + * dest queue. > >>> + */ > >>> static inline enum cds_wfcq_ret > >>> ___cds_wfcq_splice( > >>> struct cds_wfcq_head *dest_q_head, > >>> @@ -408,14 +433,26 @@ ___cds_wfcq_splice( > >>> int blocking) > >>> { > >>> struct cds_wfcq_node *head, *tail; > >>> + int attempt = 0; > >> > >> +again: > >> > >>> > >>> if (_cds_wfcq_empty(src_q_head, src_q_tail)) > >>> return CDS_WFCQ_RET_SRC_EMPTY; > >>> > >>> - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); > >>> - if (head == CDS_WFCQ_WOULDBLOCK) > >>> - return CDS_WFCQ_RET_WOULDBLOCK; > >>> - _cds_wfcq_node_init(&src_q_head->node); > >>> + for (;;) { > >>> + head = uatomic_xchg(&src_q_head->node.next, NULL); > >>> + if (head) > >>> + break; /* non-empty */ > >>> + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) > >>> + return CDS_WFCQ_RET_SRC_EMPTY; > >>> + if (!blocking) > >>> + return CDS_WFCQ_RET_WOULDBLOCK; > >>> + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { > >>> + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > >>> + attempt = 0; > >>> + } else { > >>> + caa_cpu_relax(); > >>> + } > >>> + } > >> > >> > >> Is it OK: > >> > >> - _cds_wfcq_node_init(&src_q_head->node); > >> + head = uatomic_xchg(&src_q_head->node.next, NULL); > >> + if (!head) > >> + goto again; > > > > You are right that we can simplify the code a bit by re-using > > _cds_wfcq_empty() to test validate emptiness of the source queue, rather > > than open-code it. > > > > The only issue here is that the busy-loop (goto again) will not invoke > > caa_cpu_relax(), nor do adaptative waiting like > > ___cds_wfcq_node_sync_next() normally does. > > Don't need, it will re-enter ___cds_wfcq_node_sync_next() to do it. The ___cds_wfcq_node_sync_next is actually removed. It is replaced by the xchg of the head's next pointer. > > > Also, it does not check for > > blocking/non-blocking caller. > > we can add code to check it. > > but: > > for () { > see src_q_head->node.next is not NULL > xchg fail > } > > Is this a kind of blocking? Not sure what your code snippet does, but if there is any way that we can have to busy-loop while we are in an intermediate transient state, then we could have to block. > > > > Also, whenever possible, I like to have > > for () or do/while constructs in place to make it clear that we can loop. > > So a modification of your proposal would look like: > > > > /* Return 1 if nonblocking and needs to block, 0 otherwise */ > > static inline > > bool ___cds_wfcq_busy_wait(int *attempt, int blocking) > > { > > if (!blocking) > > return 1; > > if (+attempt >= WFCQ_ADAPT_ATTEMPTS) { > > poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > > attempt = 0; > > } else { > > caa_cpu_relax(); > > } > > return 0; > > } > > > > [...] > > > > struct cds_wfcq_node *head, *tail; > > int attempt = 0; > > > > for (;;) { > > if (_cds_wfcq_empty(src_q_head, src_q_tail)) > > return CDS_WFCQ_RET_SRC_EMPTY; > > head = uatomic_xchg(&src_q_head->node.next, NULL); > > if (head) > > break; > > if (___cds_wfcq_busy_wait(&attempt, blocking)) > > return CDS_WFCQ_RET_WOULDBLOCK; > > return _cds_wfcq_empty(src_q_head, src_q_tail) ? CDS_WFCQ_RET_SRC_EMPTY : CDS_WFCQ_RET_WOULDBLOCK I'm not sure it really buys us anything semantically: we already checked that the queue was non-empty, then xchg returns that head next pointer is NULL, so we have seen an null head next, but with tail not pointing to the head node, so we are in a state that could make us busy-wait. So rather than checking again if the queue is still in a transient state, we can return CDS_WFCQ_RET_WOULDBLOCK immediately, no ? The only advantage of checking it again is to catch a few cases where we would not have to block, but I'm not convinced this is really useful. Thoughts ? Thanks, Mathieu > > > } > > > > > > Thoughts ? > > > > Thanks, > > > > Mathieu > > > > > >> > >>> > >>> /* > >>> * Memory barrier implied before uatomic_xchg() orders store to > >>> @@ -435,14 +472,13 @@ ___cds_wfcq_splice( > >>> return CDS_WFCQ_RET_DEST_EMPTY; > >>> } > >>> > >>> - > >>> /* > >>> * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > >>> * > >>> * Dequeue all nodes from src_q. > >>> * dest_q must be already initialized. > >>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > >>> - * by the caller. > >>> + * Mutual exclusion for src_q should be ensured by the caller as > >>> + * specified in the "Synchronisation table". > >>> * Returns enum cds_wfcq_ret which indicates the state of the src or > >>> * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > >>> */ > >>> diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h > >>> index ddf6b87..d9ec534 100644 > >>> --- a/urcu/wfcqueue.h > >>> +++ b/urcu/wfcqueue.h > >>> @@ -46,7 +46,7 @@ extern "C" { > >>> #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) > >>> > >>> enum cds_wfcq_ret { > >>> - CDS_WFCQ_RET_WOULDBLOCK = -1, > >>> + CDS_WFCQ_RET_WOULDBLOCK = -1, > >>> CDS_WFCQ_RET_DEST_EMPTY = 0, > >>> CDS_WFCQ_RET_DEST_NON_EMPTY = 1, > >>> CDS_WFCQ_RET_SRC_EMPTY = 2, > >>> @@ -110,13 +110,28 @@ struct cds_wfcq_tail { > >>> /* > >>> * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > >>> * > >>> - * Unless otherwise stated, the caller must ensure mutual exclusion of > >>> - * queue update operations "dequeue" and "splice" (for source queue). > >>> - * Queue read operations "first" and "next", which are used by > >>> - * "for_each" iterations, need to be protected against concurrent > >>> - * "dequeue" and "splice" (for source queue) by the caller. > >>> - * "enqueue", "splice" (for destination queue), and "empty" are the only > >>> - * operations that can be used without any mutual exclusion. > >>> + * Synchronization table: > >>> + * > >>> + * External synchronization techniques described in the API below is > >>> + * required between pairs marked with "X". No external synchronization > >>> + * required between pairs marked with "-". > >>> + * > >>> + * Legend: > >>> + * [1] cds_wfcq_enqueue > >>> + * [2] __cds_wfcq_splice (destination queue) > >>> + * [3] __cds_wfcq_dequeue > >>> + * [4] __cds_wfcq_splice (source queue) > >>> + * [5] __cds_wfcq_first > >>> + * [6] __cds_wfcq_next > >>> + * > >>> + * [1] [2] [3] [4] [5] [6] > >>> + * [1] - - - - - - > >>> + * [2] - - - - - - > >>> + * [3] - - X X X X > >>> + * [4] - - X - X X > >>> + * [5] - - X X - - > >>> + * [6] - - X X - - > >>> + * > >>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > >>> * > >>> * For convenience, cds_wfcq_dequeue_blocking() and > >>> @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > >>> * > >>> * Dequeue all nodes from src_q. > >>> * dest_q must be already initialized. > >>> - * Content written into the node before enqueue is guaranteed to be > >>> - * consistent, but no other memory ordering is ensured. > >>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > >>> - * by the caller. > >>> - * > >>> + * Mutual exclusion for src_q should be ensured by the caller as > >>> + * specified in the "Synchronisation table". > >>> * Returns enum cds_wfcq_ret which indicates the state of the src or > >>> - * dest queue. Cannot block. > >>> + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > >>> */ > >>> extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( > >>> struct cds_wfcq_head *dest_q_head, > >>> diff --git a/wfcqueue.c b/wfcqueue.c > >>> index 207df95..ab0eb93 100644 > >>> --- a/wfcqueue.c > >>> +++ b/wfcqueue.c > >>> @@ -1,7 +1,7 @@ > >>> /* > >>> * wfcqueue.c > >>> * > >>> - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue > >>> + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue > >>> * > >>> * Copyright 2010-2012 - Mathieu Desnoyers > >>> * Copyright 2011-2012 - Lai Jiangshan > >> > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Thu Nov 22 14:13:08 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Thu, 22 Nov 2012 14:13:08 -0500 Subject: [lttng-dev] [RELEASE] LTTng-UST 2.1.0-rc2 Message-ID: <20121122191308.GA18632@Krystal> LTTng-UST, the Linux Trace Toolkit Next Generation Userspace Tracer, is port of the low-overhead tracing capabilities of the LTTng kernel tracer to user-space. The library "liblttng-ust" enables tracing of applications and libraries. You will need to upgrade lttng-tools to 2.1.0-rc8 to use this release. Noteworthy changes: we had to change the ABI for filters, so we send along a sequence number used to order their execution. This will enable us to handle future bytecode side-effects in a pre-defined order. This ABI has been introduced in 2.1.0-rc1, so we did not break any stable release ABI. Other noteworthy change: UST now supports having the same event enabled multiple times, and overlapping wildcards, overlapping wildcards&event, without unexpected behaviors (e.g. before these changes, UST would be logging the same event twice into the trace if enabled by two wildcards). Many lines of code were touched by this RC, mainly due to a cleanup patch: "Cleanup: add lttng_/lttng-/LTTNG_ prefixes". It does not modify any behavior, and is a cleanup-only patch. Changelog: 2012-11-22 lttng-ust 2.1.0-rc2 * filter interpreter cleanup: use uint64_t for retval * Fix: filter linking can dereference NULL pointer on alloc failure * Cleanup: remove whitespaces and EOL in tests * Filter: use only single lower bit of filter return value * Fix: filter: var len array at end of external structure * Fix: filter link fail handling * Fix: add missing seqnum field to filter * filters: perform union rather than intersection * Implement support for overlapping wildcard/events * Cleanup: add lttng_/lttng-/LTTNG_ prefixes * filter: add seqnum field to filter command * Filter iteration: iterate on list of filters * document that tracepoint names should ideally not be re-used * Remove LIBFORMAT config declaration, unused * Add libc errno translation layer to UST error code * Fix: add const qualifier for filter local void * * Fix: re-allow non-lvalue string, sequence, array parameters * Tear down handles associated with a closed sessiond socket * Distinguish UST return codes from transport return codes * Fix: Conditionally disable tests requiring shared libs support * Cleanup: don't spawn per-user thread if HOME is not set * Manpage: document supported UST contexts * Fix: procname context semantic * Fix: Fix self-assign warning on struct ustfork_clone_info init * Fix: memcpy of string is larger than source * Implement liblttng-ust-fork daemon() override test * liblttng-ust-fork: override daemon() call * ustfork: set errno to ENOSYS if symbol lookup fails * Fix: be quiet on filter linker error * Build out of src tree * Fix: filter bytecode specializer stack leak * Fix: reloc offset validation error out on filters with no reloc table * Perform calculation on bit size in 64-bit * Use uint64_t for packet header content size and packet size * Fix: manpage typo "-lllttng-ust" -> "-llttng-ust" * Fix: BSD getprogname null pointer dereference * Add support for model.emf.uri event info * Filter error message cleanup * Manpage update: document use in daemons * Fix: get_wait_shm() ust mutex deadlock (add 2 missing exit calls) * Fix: get_wait_shm() ust mutex deadlock * Fix: add events with 0 field to field list Project website: http://lttng.org Download link: http://lttng.org/download (please refer to the README file for installation instructions) -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Thu Nov 22 14:36:36 2012 From: dgoulet at efficios.com (David Goulet) Date: Thu, 22 Nov 2012 14:36:36 -0500 Subject: [lttng-dev] [RELEASE] LTTng-tools 2.1.0-rc8 Message-ID: <50AE7EC4.8010809@efficios.com> Greetings everyone (including LTTng elves), The lttng-tools project provides a session daemon (lttng-sessiond) that acts as a tracing registry, the "lttng" command line for tracing control, a lttng-ctl library for tracing control and a lttng-relayd for network streaming. Ok so here is what happened. The lttng-ust tracer RC2 now supports enabling different filters and/or loglevels for the same event which had to be supported in lttng-tools before releasing the stable version. That said, the lttng_set_event_filter() changed to lttng_enable_event_with_filter(). This is due to the fact that, now with lttng-ust, we need to keep track of events by the name/filter/loglevel triplet rather than the event name only. For that, we needed a call that passes these three attributes at once. The original lttng_enable_event is still available but sets the filter to NULL. Now, the lttng_disable_event() still only takes an event name which will disable *all* events by that name regardless of the filter or/and loglevel. Note that this is *not* an API breakage. We only changed the filter call introduce in the 2.1 development cycle. Also, the -e, --event from the lttng add-context command was removed since lttng-ust does not support this feature (adding a context to an event). Still, adding a context to a channel is now the only possible option. In a nutshell, with lttng-tools RC8 you are able to do things like that: $ lttng enable-event ust* -u --loglevel TRACE_CRIT $ lttng enable-event ust* -u --loglevel-only TRACE_DEBUG Which will record every ust* wildcard event of TRACE_CRIT level and DEBUG only. Same concept for filters: $ lttng enable-event ust* -u --filter "intfield < 3" $ lttng enable-event ust-test* -u --filter "intfield > 15" Here is the full Changelog. 2012-11-22 lttng-tools 2.1.0-rc8 * Fix: Uninit. variable in lttng view * Add already enabled UST event error code * lttng.h API update: set filter becomes enable event with filter * Change the UST event hash table match function * Pass lttng_event struct to the set_filter API call * Adding context to an event is no longer possible * Add UST overlap tests * Add filter sequence number to UST * Fix: Typo from a previous patch in an assert() * Fix: Warn if session is running with lttng view * Fix: Add bash requirement to README for make check * Fix: add the notion of domain to lttng.1 man page * Enable additional kernel probes * Update CodingStyle * Use the new functions for default subbuf sizes * Add default subbuf sizes getter functions * Add max() and min() macro in common Please feel free to email the list about any questions/comments concerning this release. Using it is testing it! Project website: http://lttng.org/lttng2.0 Download link: http://lttng.org/files/lttng-tools/lttng-tools-2.1.0-rc8.tar.bz2 (for the PGP signature, same file with .asc appended) Cheers! David From laijs at cn.fujitsu.com Thu Nov 22 21:23:03 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Fri, 23 Nov 2012 10:23:03 +0800 Subject: [lttng-dev] [PATCH 14/16] urcu-qsbr: batch concurrent synchronize_rcu() In-Reply-To: <20121122183041.GB2829@linux.vnet.ibm.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-15-git-send-email-mathieu.desnoyers@efficios.com> <50AC8F56.6040109@cn.fujitsu.com> <20121121183304.GA25932@Krystal> <50ADEAAF.1010703@cn.fujitsu.com> <20121122183041.GB2829@linux.vnet.ibm.com> Message-ID: <50AEDE07.6040705@cn.fujitsu.com> On 11/23/2012 02:30 AM, Paul E. McKenney wrote: > On Thu, Nov 22, 2012 at 05:04:47PM +0800, Lai Jiangshan wrote: >> On 11/22/2012 02:33 AM, Mathieu Desnoyers wrote: >>> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: >>>> Could you delay 14~16 for 40 days if I don't implement it in 40 days? >>> >>> I'm curious to know more about the changes you are planning. Is that >>> another way to implement grace periods that would allow multiple threads >>> to execute synchronize_rcu() concurrently ? >> >> synchronize_rcu()s in this implement share coarse-grain step(1 GP) >> to achieve concurrence. My implement will use fine-grain step(1 check or 1 flip) >> like SRCU. and call_rcu() is also considered in this implement to avoid >> unneeded wait. >> >>> >>> Please note that changes in these algorithms will need to go through >>> very strict review/validation/verification. So I expect that if it takes >>> 40 days to implement, we can plan at least 3-4 months of validation work. >> >> I means I don't have time. If I can't steal some time from the late 40 days, >> this code is OK for me. > > Why don't we take the current code, which would allow some academic > projects to test on large systems in the next few months, and then > replace it with your code when available and if appropriate? > Agreed. thanks, Lai From laijs at cn.fujitsu.com Thu Nov 22 21:43:48 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Fri, 23 Nov 2012 10:43:48 +0800 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <20121122185455.GA17756@Krystal> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> <50AC93E0.1050204@cn.fujitsu.com> <20121121151823.GB21518@Krystal> <50ADE76F.7090006@cn.fujitsu.com> <20121122185455.GA17756@Krystal> Message-ID: <50AEE2E4.90209@cn.fujitsu.com> On 11/23/2012 02:54 AM, Mathieu Desnoyers wrote: > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: >> On 11/21/2012 11:18 PM, Mathieu Desnoyers wrote: >>> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: >>>> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: >>>>> A carefully crafted splice operation does not need to use an external >>>>> mutex to synchronize against other splice operations. >>>>> >>>>> The trick is atomically exchange the head next pointer with >>>>> NULL. If the pointer we replaced was NULL, it means the queue was >>>>> possibly empty. If head next was not NULL, by setting head to NULL, we >>>>> ensure that concurrent splice operations are going to see an empty >>>>> queue, even if concurrent enqueue operations move tail further. This >>>>> means that as long as we are within splice, after setting head to NULL, >>>>> but before moving tail back to head, concurrent splice operations will >>>>> always see an empty queue, therefore acting as mutual exclusion. >>>>> >>>>> If exchange returns a NULL head, we confirm that it was indeed empty by >>>>> checking if the tail pointer points to the head node, busy-waiting if >>>>> necessary. >>>>> >>>>> Then the last step is to move the tail pointer to head. At that point, >>>>> enqueuers are going to start enqueuing at head again, and other splice >>>>> operations will be able to proceed. >>>>> >>>>> Signed-off-by: Mathieu Desnoyers >>>>> --- >>>>> urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ >>>>> urcu/wfcqueue.h | 40 ++++++++++++++++++---------- >>>>> wfcqueue.c | 2 +- >>>>> 3 files changed, 79 insertions(+), 31 deletions(-) >>>>> >>>>> diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h >>>>> index 8774c03..4b2de50 100644 >>>>> --- a/urcu/static/wfcqueue.h >>>>> +++ b/urcu/static/wfcqueue.h >>>>> @@ -46,15 +46,30 @@ extern "C" { >>>>> * half-wait-free/half-blocking queue implementation done by Paul E. >>>>> * McKenney. >>>>> * >>>>> - * Mutual exclusion of __cds_wfcq_* API >>>>> - * >>>>> - * Unless otherwise stated, the caller must ensure mutual exclusion of >>>>> - * queue update operations "dequeue" and "splice" (for source queue). >>>>> - * Queue read operations "first" and "next", which are used by >>>>> - * "for_each" iterations, need to be protected against concurrent >>>>> - * "dequeue" and "splice" (for source queue) by the caller. >>>>> - * "enqueue", "splice" (for destination queue), and "empty" are the only >>>>> - * operations that can be used without any mutual exclusion. >>>>> + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API >>>>> + * >>>>> + * Synchronization table: >>>>> + * >>>>> + * External synchronization techniques described in the API below is >>>>> + * required between pairs marked with "X". No external synchronization >>>>> + * required between pairs marked with "-". >>>>> + * >>>>> + * Legend: >>>>> + * [1] cds_wfcq_enqueue >>>>> + * [2] __cds_wfcq_splice (destination queue) >>>>> + * [3] __cds_wfcq_dequeue >>>>> + * [4] __cds_wfcq_splice (source queue) >>>>> + * [5] __cds_wfcq_first >>>>> + * [6] __cds_wfcq_next >>>>> + * >>>>> + * [1] [2] [3] [4] [5] [6] >>>>> + * [1] - - - - - - >>>>> + * [2] - - - - - - >>>>> + * [3] - - X X X X >>>>> + * [4] - - X - X X >>>>> + * [5] - - X X - - >>>>> + * [6] - - X X - - >>>>> + * >>>>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). >>>>> * >>>>> * For convenience, cds_wfcq_dequeue_blocking() and >>>>> @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, >>>>> return ___cds_wfcq_dequeue(head, tail, 0); >>>>> } >>>>> >>>>> +/* >>>>> + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. >>>>> + * >>>>> + * Dequeue all nodes from src_q. >>>>> + * dest_q must be already initialized. >>>>> + * Mutual exclusion for src_q should be ensured by the caller as >>>>> + * specified in the "Synchronisation table". >>>>> + * Returns enum cds_wfcq_ret which indicates the state of the src or >>>>> + * dest queue. >>>>> + */ >>>>> static inline enum cds_wfcq_ret >>>>> ___cds_wfcq_splice( >>>>> struct cds_wfcq_head *dest_q_head, >>>>> @@ -408,14 +433,26 @@ ___cds_wfcq_splice( >>>>> int blocking) >>>>> { >>>>> struct cds_wfcq_node *head, *tail; >>>>> + int attempt = 0; >>>> >>>> +again: >>>> >>>>> >>>>> if (_cds_wfcq_empty(src_q_head, src_q_tail)) >>>>> return CDS_WFCQ_RET_SRC_EMPTY; >>>>> >>>>> - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); >>>>> - if (head == CDS_WFCQ_WOULDBLOCK) >>>>> - return CDS_WFCQ_RET_WOULDBLOCK; >>>>> - _cds_wfcq_node_init(&src_q_head->node); >>>>> + for (;;) { >>>>> + head = uatomic_xchg(&src_q_head->node.next, NULL); >>>>> + if (head) >>>>> + break; /* non-empty */ >>>>> + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) >>>>> + return CDS_WFCQ_RET_SRC_EMPTY; >>>>> + if (!blocking) >>>>> + return CDS_WFCQ_RET_WOULDBLOCK; >>>>> + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { >>>>> + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ >>>>> + attempt = 0; >>>>> + } else { >>>>> + caa_cpu_relax(); >>>>> + } >>>>> + } >>>> >>>> >>>> Is it OK: >>>> >>>> - _cds_wfcq_node_init(&src_q_head->node); >>>> + head = uatomic_xchg(&src_q_head->node.next, NULL); >>>> + if (!head) >>>> + goto again; >>> >>> You are right that we can simplify the code a bit by re-using >>> _cds_wfcq_empty() to test validate emptiness of the source queue, rather >>> than open-code it. >>> >>> The only issue here is that the busy-loop (goto again) will not invoke >>> caa_cpu_relax(), nor do adaptative waiting like >>> ___cds_wfcq_node_sync_next() normally does. >> >> Don't need, it will re-enter ___cds_wfcq_node_sync_next() to do it. > > The ___cds_wfcq_node_sync_next is actually removed. It is replaced by > the xchg of the head's next pointer. It is kept. { struct cds_wfcq_node *head, *tail; +agrain: if (_cds_wfcq_empty(src_q_head, src_q_tail)) return CDS_WFCQ_RET_SRC_EMPTY; head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); if (head == CDS_WFCQ_WOULDBLOCK) return CDS_WFCQ_RET_WOULDBLOCK; - _cds_wfcq_node_init(&src_q_head->node); + head = uatomic_xchg(&src_q_head->node.next, NULL); + if (!head) + goto again; /* * Memory barrier implied before uatomic_xchg() orders store to > >> >>> Also, it does not check for >>> blocking/non-blocking caller. >> >> we can add code to check it. >> >> but: >> >> for () { >> see src_q_head->node.next is not NULL >> xchg fail >> } >> >> Is this a kind of blocking? > > Not sure what your code snippet does, but if there is any way that we > can have to busy-loop while we are in an intermediate transient state, > then we could have to block. > See above. >> >> >>> Also, whenever possible, I like to have >>> for () or do/while constructs in place to make it clear that we can loop. >>> So a modification of your proposal would look like: >>> >>> /* Return 1 if nonblocking and needs to block, 0 otherwise */ >>> static inline >>> bool ___cds_wfcq_busy_wait(int *attempt, int blocking) >>> { >>> if (!blocking) >>> return 1; >>> if (+attempt >= WFCQ_ADAPT_ATTEMPTS) { >>> poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ >>> attempt = 0; >>> } else { >>> caa_cpu_relax(); >>> } >>> return 0; >>> } >>> >>> [...] >>> >>> struct cds_wfcq_node *head, *tail; >>> int attempt = 0; >>> >>> for (;;) { >>> if (_cds_wfcq_empty(src_q_head, src_q_tail)) >>> return CDS_WFCQ_RET_SRC_EMPTY; >>> head = uatomic_xchg(&src_q_head->node.next, NULL); >>> if (head) >>> break; >>> if (___cds_wfcq_busy_wait(&attempt, blocking)) >>> return CDS_WFCQ_RET_WOULDBLOCK; >> >> return _cds_wfcq_empty(src_q_head, src_q_tail) ? CDS_WFCQ_RET_SRC_EMPTY : CDS_WFCQ_RET_WOULDBLOCK > > I'm not sure it really buys us anything semantically: we already checked > that the queue was non-empty, then xchg returns that head next pointer > is NULL, so we have seen an null head next, but with tail not pointing > to the head node, so we are in a state that could make us busy-wait. So > rather than checking again if the queue is still in a transient state, > we can return CDS_WFCQ_RET_WOULDBLOCK immediately, no ? The only > advantage of checking it again is to catch a few cases where we would > not have to block, but I'm not convinced this is really useful. If some other beat us and win, the queue is currently empty, we should return CDS_WFCQ_RET_SRC_EMPTY which is correct and avoid to mislead the caller. (you patch is correct in this semantic) CDS_WFCQ_RET_WOULDBLOCK: the caller knows it is not empty when call, the caller will handle some other urgent thing or relax a little if no urgent thing and then call it again quickly. CDS_WFCQ_RET_SRC_EMPTY: the caller knows it is currently empty, the caller may sleep or ... > > Thoughts ? > > Thanks, > > Mathieu > >> >>> } >>> >>> >>> Thoughts ? >>> >>> Thanks, >>> >>> Mathieu >>> >>> >>>> >>>>> >>>>> /* >>>>> * Memory barrier implied before uatomic_xchg() orders store to >>>>> @@ -435,14 +472,13 @@ ___cds_wfcq_splice( >>>>> return CDS_WFCQ_RET_DEST_EMPTY; >>>>> } >>>>> >>>>> - >>>>> /* >>>>> * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. >>>>> * >>>>> * Dequeue all nodes from src_q. >>>>> * dest_q must be already initialized. >>>>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured >>>>> - * by the caller. >>>>> + * Mutual exclusion for src_q should be ensured by the caller as >>>>> + * specified in the "Synchronisation table". >>>>> * Returns enum cds_wfcq_ret which indicates the state of the src or >>>>> * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. >>>>> */ >>>>> diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h >>>>> index ddf6b87..d9ec534 100644 >>>>> --- a/urcu/wfcqueue.h >>>>> +++ b/urcu/wfcqueue.h >>>>> @@ -46,7 +46,7 @@ extern "C" { >>>>> #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) >>>>> >>>>> enum cds_wfcq_ret { >>>>> - CDS_WFCQ_RET_WOULDBLOCK = -1, >>>>> + CDS_WFCQ_RET_WOULDBLOCK = -1, >>>>> CDS_WFCQ_RET_DEST_EMPTY = 0, >>>>> CDS_WFCQ_RET_DEST_NON_EMPTY = 1, >>>>> CDS_WFCQ_RET_SRC_EMPTY = 2, >>>>> @@ -110,13 +110,28 @@ struct cds_wfcq_tail { >>>>> /* >>>>> * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API >>>>> * >>>>> - * Unless otherwise stated, the caller must ensure mutual exclusion of >>>>> - * queue update operations "dequeue" and "splice" (for source queue). >>>>> - * Queue read operations "first" and "next", which are used by >>>>> - * "for_each" iterations, need to be protected against concurrent >>>>> - * "dequeue" and "splice" (for source queue) by the caller. >>>>> - * "enqueue", "splice" (for destination queue), and "empty" are the only >>>>> - * operations that can be used without any mutual exclusion. >>>>> + * Synchronization table: >>>>> + * >>>>> + * External synchronization techniques described in the API below is >>>>> + * required between pairs marked with "X". No external synchronization >>>>> + * required between pairs marked with "-". >>>>> + * >>>>> + * Legend: >>>>> + * [1] cds_wfcq_enqueue >>>>> + * [2] __cds_wfcq_splice (destination queue) >>>>> + * [3] __cds_wfcq_dequeue >>>>> + * [4] __cds_wfcq_splice (source queue) >>>>> + * [5] __cds_wfcq_first >>>>> + * [6] __cds_wfcq_next >>>>> + * >>>>> + * [1] [2] [3] [4] [5] [6] >>>>> + * [1] - - - - - - >>>>> + * [2] - - - - - - >>>>> + * [3] - - X X X X >>>>> + * [4] - - X - X X >>>>> + * [5] - - X X - - >>>>> + * [6] - - X X - - >>>>> + * >>>>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). >>>>> * >>>>> * For convenience, cds_wfcq_dequeue_blocking() and >>>>> @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( >>>>> * >>>>> * Dequeue all nodes from src_q. >>>>> * dest_q must be already initialized. >>>>> - * Content written into the node before enqueue is guaranteed to be >>>>> - * consistent, but no other memory ordering is ensured. >>>>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured >>>>> - * by the caller. >>>>> - * >>>>> + * Mutual exclusion for src_q should be ensured by the caller as >>>>> + * specified in the "Synchronisation table". >>>>> * Returns enum cds_wfcq_ret which indicates the state of the src or >>>>> - * dest queue. Cannot block. >>>>> + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. >>>>> */ >>>>> extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( >>>>> struct cds_wfcq_head *dest_q_head, >>>>> diff --git a/wfcqueue.c b/wfcqueue.c >>>>> index 207df95..ab0eb93 100644 >>>>> --- a/wfcqueue.c >>>>> +++ b/wfcqueue.c >>>>> @@ -1,7 +1,7 @@ >>>>> /* >>>>> * wfcqueue.c >>>>> * >>>>> - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue >>>>> + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue >>>>> * >>>>> * Copyright 2010-2012 - Mathieu Desnoyers >>>>> * Copyright 2011-2012 - Lai Jiangshan >>>> >>> >> > From Paul_Woegerer at mentor.com Fri Nov 23 03:07:18 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Fri, 23 Nov 2012 09:07:18 +0100 Subject: [lttng-dev] Emitting events from shared object constructors is (currently) not possible In-Reply-To: <20121122164512.GA16119@Krystal> References: <50AE31E8.4040507@mentor.com> <20121122153901.GA14685@Krystal> <50AE4CEF.9050809@mentor.com> <20121122164512.GA16119@Krystal> Message-ID: <50AF2EB6.8090706@mentor.com> On 11/22/2012 05:45 PM, Mathieu Desnoyers wrote: > * Woegerer, Paul (Paul_Woegerer at mentor.com) wrote: >> In case the probes would be defined in different shared object from the >> one where they are used we wouldn't have a problem at all because the >> dynamic linker would invoke all the constructor functions for the probe >> shared object before the constructor functions of the shared object that >> has a dependency to the probe shared object, right ? > > The instrumented code does not have dependency on the probe shared > object, so we can ship applications separately from their probe .so. So > unfortunately, the linker is not doing this for us. But still, to come back to my original request, whenever the tracepoint provider is statically linked to the tracepoint user (which is a valid lttng-ust use case, right ?) it is not possible to emit tracepoints in object constructors as long as object constructors defined in lttng/tracepoint.h and lttng/ust-tracepoint-event.h are simply using __attribute__((constructor)) instead of e.g. __attribute__((constructor (1000))). Without this change the user simply cannot make sure its own constructor gets invoked after the trace provider constructors. >> And even if this is not the case I could explicitly dlopen the probe >> shared object from within my constructor function and thus make sure >> that the constructor function of the probe shared object gets called >> before I emit an event from my constructor function. > > The idea would be to provide a nice API to facilitate this use-case, and > document it in the instrumentation guide-lines (lttng-ust(3)). Therefore we would need to reliably deduce the tracepoint provider shared library name from the header file that defines it. Since C/C++ has no package concept and gives you the freedom to name your shared library whatever you like it seems to be hard to get there. One way to deal with it would be to extend the lttng-gen-tp tool directly build the tracepoint provider shared library instead of just outputting the generated .c .h files. This way the shared library name would be controlled by lttng-gen-tp tool and an autogenerated macro (e.g. ensure_tracepoints_init()) in the generated .h file could provide the dlopen code to explicitly load the tracepoint provider shared library if needed. Thanks, Paul -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From mathieu.desnoyers at efficios.com Fri Nov 23 09:55:45 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 23 Nov 2012 09:55:45 -0500 Subject: [lttng-dev] [PATCH 06/16] wfcqueue: implement mutex-free splice In-Reply-To: <50AEE2E4.90209@cn.fujitsu.com> References: <1353440429-19223-1-git-send-email-mathieu.desnoyers@efficios.com> <1353440429-19223-7-git-send-email-mathieu.desnoyers@efficios.com> <50AC93E0.1050204@cn.fujitsu.com> <20121121151823.GB21518@Krystal> <50ADE76F.7090006@cn.fujitsu.com> <20121122185455.GA17756@Krystal> <50AEE2E4.90209@cn.fujitsu.com> Message-ID: <20121123145545.GA1815@Krystal> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > On 11/23/2012 02:54 AM, Mathieu Desnoyers wrote: > > * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > >> On 11/21/2012 11:18 PM, Mathieu Desnoyers wrote: > >>> * Lai Jiangshan (laijs at cn.fujitsu.com) wrote: > >>>> On 11/21/2012 03:40 AM, Mathieu Desnoyers wrote: > >>>>> A carefully crafted splice operation does not need to use an external > >>>>> mutex to synchronize against other splice operations. > >>>>> > >>>>> The trick is atomically exchange the head next pointer with > >>>>> NULL. If the pointer we replaced was NULL, it means the queue was > >>>>> possibly empty. If head next was not NULL, by setting head to NULL, we > >>>>> ensure that concurrent splice operations are going to see an empty > >>>>> queue, even if concurrent enqueue operations move tail further. This > >>>>> means that as long as we are within splice, after setting head to NULL, > >>>>> but before moving tail back to head, concurrent splice operations will > >>>>> always see an empty queue, therefore acting as mutual exclusion. > >>>>> > >>>>> If exchange returns a NULL head, we confirm that it was indeed empty by > >>>>> checking if the tail pointer points to the head node, busy-waiting if > >>>>> necessary. > >>>>> > >>>>> Then the last step is to move the tail pointer to head. At that point, > >>>>> enqueuers are going to start enqueuing at head again, and other splice > >>>>> operations will be able to proceed. > >>>>> > >>>>> Signed-off-by: Mathieu Desnoyers > >>>>> --- > >>>>> urcu/static/wfcqueue.h | 68 ++++++++++++++++++++++++++++++++++++------------ > >>>>> urcu/wfcqueue.h | 40 ++++++++++++++++++---------- > >>>>> wfcqueue.c | 2 +- > >>>>> 3 files changed, 79 insertions(+), 31 deletions(-) > >>>>> > >>>>> diff --git a/urcu/static/wfcqueue.h b/urcu/static/wfcqueue.h > >>>>> index 8774c03..4b2de50 100644 > >>>>> --- a/urcu/static/wfcqueue.h > >>>>> +++ b/urcu/static/wfcqueue.h > >>>>> @@ -46,15 +46,30 @@ extern "C" { > >>>>> * half-wait-free/half-blocking queue implementation done by Paul E. > >>>>> * McKenney. > >>>>> * > >>>>> - * Mutual exclusion of __cds_wfcq_* API > >>>>> - * > >>>>> - * Unless otherwise stated, the caller must ensure mutual exclusion of > >>>>> - * queue update operations "dequeue" and "splice" (for source queue). > >>>>> - * Queue read operations "first" and "next", which are used by > >>>>> - * "for_each" iterations, need to be protected against concurrent > >>>>> - * "dequeue" and "splice" (for source queue) by the caller. > >>>>> - * "enqueue", "splice" (for destination queue), and "empty" are the only > >>>>> - * operations that can be used without any mutual exclusion. > >>>>> + * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > >>>>> + * > >>>>> + * Synchronization table: > >>>>> + * > >>>>> + * External synchronization techniques described in the API below is > >>>>> + * required between pairs marked with "X". No external synchronization > >>>>> + * required between pairs marked with "-". > >>>>> + * > >>>>> + * Legend: > >>>>> + * [1] cds_wfcq_enqueue > >>>>> + * [2] __cds_wfcq_splice (destination queue) > >>>>> + * [3] __cds_wfcq_dequeue > >>>>> + * [4] __cds_wfcq_splice (source queue) > >>>>> + * [5] __cds_wfcq_first > >>>>> + * [6] __cds_wfcq_next > >>>>> + * > >>>>> + * [1] [2] [3] [4] [5] [6] > >>>>> + * [1] - - - - - - > >>>>> + * [2] - - - - - - > >>>>> + * [3] - - X X X X > >>>>> + * [4] - - X - X X > >>>>> + * [5] - - X X - - > >>>>> + * [6] - - X X - - > >>>>> + * > >>>>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > >>>>> * > >>>>> * For convenience, cds_wfcq_dequeue_blocking() and > >>>>> @@ -399,6 +414,16 @@ ___cds_wfcq_dequeue_nonblocking(struct cds_wfcq_head *head, > >>>>> return ___cds_wfcq_dequeue(head, tail, 0); > >>>>> } > >>>>> > >>>>> +/* > >>>>> + * __cds_wfcq_splice: enqueue all src_q nodes at the end of dest_q. > >>>>> + * > >>>>> + * Dequeue all nodes from src_q. > >>>>> + * dest_q must be already initialized. > >>>>> + * Mutual exclusion for src_q should be ensured by the caller as > >>>>> + * specified in the "Synchronisation table". > >>>>> + * Returns enum cds_wfcq_ret which indicates the state of the src or > >>>>> + * dest queue. > >>>>> + */ > >>>>> static inline enum cds_wfcq_ret > >>>>> ___cds_wfcq_splice( > >>>>> struct cds_wfcq_head *dest_q_head, > >>>>> @@ -408,14 +433,26 @@ ___cds_wfcq_splice( > >>>>> int blocking) > >>>>> { > >>>>> struct cds_wfcq_node *head, *tail; > >>>>> + int attempt = 0; > >>>> > >>>> +again: > >>>> > >>>>> > >>>>> if (_cds_wfcq_empty(src_q_head, src_q_tail)) > >>>>> return CDS_WFCQ_RET_SRC_EMPTY; > >>>>> > >>>>> - head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); > >>>>> - if (head == CDS_WFCQ_WOULDBLOCK) > >>>>> - return CDS_WFCQ_RET_WOULDBLOCK; > >>>>> - _cds_wfcq_node_init(&src_q_head->node); > >>>>> + for (;;) { > >>>>> + head = uatomic_xchg(&src_q_head->node.next, NULL); > >>>>> + if (head) > >>>>> + break; /* non-empty */ > >>>>> + if (CMM_LOAD_SHARED(src_q_tail->p) == &src_q_head->node) > >>>>> + return CDS_WFCQ_RET_SRC_EMPTY; > >>>>> + if (!blocking) > >>>>> + return CDS_WFCQ_RET_WOULDBLOCK; > >>>>> + if (++attempt >= WFCQ_ADAPT_ATTEMPTS) { > >>>>> + poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > >>>>> + attempt = 0; > >>>>> + } else { > >>>>> + caa_cpu_relax(); > >>>>> + } > >>>>> + } > >>>> > >>>> > >>>> Is it OK: > >>>> > >>>> - _cds_wfcq_node_init(&src_q_head->node); > >>>> + head = uatomic_xchg(&src_q_head->node.next, NULL); > >>>> + if (!head) > >>>> + goto again; > >>> > >>> You are right that we can simplify the code a bit by re-using > >>> _cds_wfcq_empty() to test validate emptiness of the source queue, rather > >>> than open-code it. > >>> > >>> The only issue here is that the busy-loop (goto again) will not invoke > >>> caa_cpu_relax(), nor do adaptative waiting like > >>> ___cds_wfcq_node_sync_next() normally does. > >> > >> Don't need, it will re-enter ___cds_wfcq_node_sync_next() to do it. > > > > The ___cds_wfcq_node_sync_next is actually removed. It is replaced by > > the xchg of the head's next pointer. > > It is kept. > > { > struct cds_wfcq_node *head, *tail; > > +agrain: > if (_cds_wfcq_empty(src_q_head, src_q_tail)) > return CDS_WFCQ_RET_SRC_EMPTY; > > head = ___cds_wfcq_node_sync_next(&src_q_head->node, blocking); > if (head == CDS_WFCQ_WOULDBLOCK) > return CDS_WFCQ_RET_WOULDBLOCK; > - _cds_wfcq_node_init(&src_q_head->node); > + head = uatomic_xchg(&src_q_head->node.next, NULL); > + if (!head) > + goto again; I'm afraid this won't work. Let's suppose we have a queue initially containing 1 node, and we have 2 threads executing splice(): Thread A Thread B splice() splice() -> not empty -> not empty -> sync_next fetch head -> xchg head with NULL -> finish splice. -> sync_next finds NULL head. [ busy-loop forever ] As we see, we need the sync_next operation to re-check for queue emptiness rather than re-trying until it finds a non-NULL next pointer. Thanks, Mathieu > > /* > * Memory barrier implied before uatomic_xchg() orders store to > > > > > >> > >>> Also, it does not check for > >>> blocking/non-blocking caller. > >> > >> we can add code to check it. > >> > >> but: > >> > >> for () { > >> see src_q_head->node.next is not NULL > >> xchg fail > >> } > >> > >> Is this a kind of blocking? > > > > Not sure what your code snippet does, but if there is any way that we > > can have to busy-loop while we are in an intermediate transient state, > > then we could have to block. > > > > See above. > > >> > >> > >>> Also, whenever possible, I like to have > >>> for () or do/while constructs in place to make it clear that we can loop. > >>> So a modification of your proposal would look like: > >>> > >>> /* Return 1 if nonblocking and needs to block, 0 otherwise */ > >>> static inline > >>> bool ___cds_wfcq_busy_wait(int *attempt, int blocking) > >>> { > >>> if (!blocking) > >>> return 1; > >>> if (+attempt >= WFCQ_ADAPT_ATTEMPTS) { > >>> poll(NULL, 0, WFCQ_WAIT); /* Wait for 10ms */ > >>> attempt = 0; > >>> } else { > >>> caa_cpu_relax(); > >>> } > >>> return 0; > >>> } > >>> > >>> [...] > >>> > >>> struct cds_wfcq_node *head, *tail; > >>> int attempt = 0; > >>> > >>> for (;;) { > >>> if (_cds_wfcq_empty(src_q_head, src_q_tail)) > >>> return CDS_WFCQ_RET_SRC_EMPTY; > >>> head = uatomic_xchg(&src_q_head->node.next, NULL); > >>> if (head) > >>> break; > >>> if (___cds_wfcq_busy_wait(&attempt, blocking)) > >>> return CDS_WFCQ_RET_WOULDBLOCK; > >> > >> return _cds_wfcq_empty(src_q_head, src_q_tail) ? CDS_WFCQ_RET_SRC_EMPTY : CDS_WFCQ_RET_WOULDBLOCK > > > > I'm not sure it really buys us anything semantically: we already checked > > that the queue was non-empty, then xchg returns that head next pointer > > is NULL, so we have seen an null head next, but with tail not pointing > > to the head node, so we are in a state that could make us busy-wait. So > > rather than checking again if the queue is still in a transient state, > > we can return CDS_WFCQ_RET_WOULDBLOCK immediately, no ? The only > > advantage of checking it again is to catch a few cases where we would > > not have to block, but I'm not convinced this is really useful. > > > If some other beat us and win, the queue is currently empty, > we should return CDS_WFCQ_RET_SRC_EMPTY which is correct and avoid to mislead the caller. > (you patch is correct in this semantic) > > CDS_WFCQ_RET_WOULDBLOCK: the caller knows it is not empty when call, > the caller will handle some other urgent thing or relax a little if no urgent thing > and then call it again quickly. > > CDS_WFCQ_RET_SRC_EMPTY: the caller knows it is currently empty, the caller may sleep or ... > > > > > Thoughts ? > > > > Thanks, > > > > Mathieu > > > >> > >>> } > >>> > >>> > >>> Thoughts ? > >>> > >>> Thanks, > >>> > >>> Mathieu > >>> > >>> > >>>> > >>>>> > >>>>> /* > >>>>> * Memory barrier implied before uatomic_xchg() orders store to > >>>>> @@ -435,14 +472,13 @@ ___cds_wfcq_splice( > >>>>> return CDS_WFCQ_RET_DEST_EMPTY; > >>>>> } > >>>>> > >>>>> - > >>>>> /* > >>>>> * __cds_wfcq_splice_blocking: enqueue all src_q nodes at the end of dest_q. > >>>>> * > >>>>> * Dequeue all nodes from src_q. > >>>>> * dest_q must be already initialized. > >>>>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > >>>>> - * by the caller. > >>>>> + * Mutual exclusion for src_q should be ensured by the caller as > >>>>> + * specified in the "Synchronisation table". > >>>>> * Returns enum cds_wfcq_ret which indicates the state of the src or > >>>>> * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > >>>>> */ > >>>>> diff --git a/urcu/wfcqueue.h b/urcu/wfcqueue.h > >>>>> index ddf6b87..d9ec534 100644 > >>>>> --- a/urcu/wfcqueue.h > >>>>> +++ b/urcu/wfcqueue.h > >>>>> @@ -46,7 +46,7 @@ extern "C" { > >>>>> #define CDS_WFCQ_WOULDBLOCK ((void *) -1UL) > >>>>> > >>>>> enum cds_wfcq_ret { > >>>>> - CDS_WFCQ_RET_WOULDBLOCK = -1, > >>>>> + CDS_WFCQ_RET_WOULDBLOCK = -1, > >>>>> CDS_WFCQ_RET_DEST_EMPTY = 0, > >>>>> CDS_WFCQ_RET_DEST_NON_EMPTY = 1, > >>>>> CDS_WFCQ_RET_SRC_EMPTY = 2, > >>>>> @@ -110,13 +110,28 @@ struct cds_wfcq_tail { > >>>>> /* > >>>>> * Mutual exclusion of cds_wfcq_* / __cds_wfcq_* API > >>>>> * > >>>>> - * Unless otherwise stated, the caller must ensure mutual exclusion of > >>>>> - * queue update operations "dequeue" and "splice" (for source queue). > >>>>> - * Queue read operations "first" and "next", which are used by > >>>>> - * "for_each" iterations, need to be protected against concurrent > >>>>> - * "dequeue" and "splice" (for source queue) by the caller. > >>>>> - * "enqueue", "splice" (for destination queue), and "empty" are the only > >>>>> - * operations that can be used without any mutual exclusion. > >>>>> + * Synchronization table: > >>>>> + * > >>>>> + * External synchronization techniques described in the API below is > >>>>> + * required between pairs marked with "X". No external synchronization > >>>>> + * required between pairs marked with "-". > >>>>> + * > >>>>> + * Legend: > >>>>> + * [1] cds_wfcq_enqueue > >>>>> + * [2] __cds_wfcq_splice (destination queue) > >>>>> + * [3] __cds_wfcq_dequeue > >>>>> + * [4] __cds_wfcq_splice (source queue) > >>>>> + * [5] __cds_wfcq_first > >>>>> + * [6] __cds_wfcq_next > >>>>> + * > >>>>> + * [1] [2] [3] [4] [5] [6] > >>>>> + * [1] - - - - - - > >>>>> + * [2] - - - - - - > >>>>> + * [3] - - X X X X > >>>>> + * [4] - - X - X X > >>>>> + * [5] - - X X - - > >>>>> + * [6] - - X X - - > >>>>> + * > >>>>> * Mutual exclusion can be ensured by holding cds_wfcq_dequeue_lock(). > >>>>> * > >>>>> * For convenience, cds_wfcq_dequeue_blocking() and > >>>>> @@ -231,13 +246,10 @@ extern struct cds_wfcq_node *__cds_wfcq_dequeue_nonblocking( > >>>>> * > >>>>> * Dequeue all nodes from src_q. > >>>>> * dest_q must be already initialized. > >>>>> - * Content written into the node before enqueue is guaranteed to be > >>>>> - * consistent, but no other memory ordering is ensured. > >>>>> - * Dequeue/splice/iteration mutual exclusion for src_q should be ensured > >>>>> - * by the caller. > >>>>> - * > >>>>> + * Mutual exclusion for src_q should be ensured by the caller as > >>>>> + * specified in the "Synchronisation table". > >>>>> * Returns enum cds_wfcq_ret which indicates the state of the src or > >>>>> - * dest queue. Cannot block. > >>>>> + * dest queue. Never returns CDS_WFCQ_RET_WOULDBLOCK. > >>>>> */ > >>>>> extern enum cds_wfcq_ret __cds_wfcq_splice_blocking( > >>>>> struct cds_wfcq_head *dest_q_head, > >>>>> diff --git a/wfcqueue.c b/wfcqueue.c > >>>>> index 207df95..ab0eb93 100644 > >>>>> --- a/wfcqueue.c > >>>>> +++ b/wfcqueue.c > >>>>> @@ -1,7 +1,7 @@ > >>>>> /* > >>>>> * wfcqueue.c > >>>>> * > >>>>> - * Userspace RCU library - Concurrent queue with Wait-Free Enqueue/Blocking Dequeue > >>>>> + * Userspace RCU library - Concurrent Queue with Wait-Free Enqueue/Blocking Dequeue > >>>>> * > >>>>> * Copyright 2010-2012 - Mathieu Desnoyers > >>>>> * Copyright 2011-2012 - Lai Jiangshan > >>>> > >>> > >> > > > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Fri Nov 23 15:01:05 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 23 Nov 2012 15:01:05 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Add file: lttng-kernel-version.h Message-ID: <1353700865-32009-1-git-send-email-simon.marchi@polymtl.ca> It contains a macro to help checking for kernel version ranges. Signed-off-by: Simon Marchi --- lttng-kernel-version.h | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-) create mode 100644 lttng-kernel-version.h diff --git a/lttng-kernel-version.h b/lttng-kernel-version.h new file mode 100644 index 0000000..cb5c4dd --- /dev/null +++ b/lttng-kernel-version.h @@ -0,0 +1,36 @@ +#ifndef _LTTNG_KERNEL_VERSION_H +#define _LTTNG_KERNEL_VERSION_H + +/* + * lttng-events.h + * + * Contains helpers to check more complex kernel version conditions. + * + * Copyright (C) 2012 Mathieu Desnoyers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; only + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/* + * This macro checks if the kernel version is between the two specified + * versions. + */ +#define LTTNG_KERNEL_RANGE(a_low, b_low, c_low, a_high, b_high, c_high) \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(a_low, b_low, c_low) && \ + LINUX_VERSION_CODE <= KERNEL_VERSION(a_high, b_high, c_high)) + +#endif /* _LTTNG_KERNEL_VERSION_H */ -- 1.7.1 From mathieu.desnoyers at efficios.com Fri Nov 23 15:06:55 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 23 Nov 2012 15:06:55 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Add file: lttng-kernel-version.h In-Reply-To: <1353700865-32009-1-git-send-email-simon.marchi@polymtl.ca> References: <1353700865-32009-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121123200655.GA11335@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > It contains a macro to help checking for kernel version ranges. Merged with small cosmetic changes, Oh damn, I forgot the --author. Sorry, it appears From: me. Thanks, Mathieu > > Signed-off-by: Simon Marchi > --- > lttng-kernel-version.h | 36 ++++++++++++++++++++++++++++++++++++ > 1 files changed, 36 insertions(+), 0 deletions(-) > create mode 100644 lttng-kernel-version.h > > diff --git a/lttng-kernel-version.h b/lttng-kernel-version.h > new file mode 100644 > index 0000000..cb5c4dd > --- /dev/null > +++ b/lttng-kernel-version.h > @@ -0,0 +1,36 @@ > +#ifndef _LTTNG_KERNEL_VERSION_H > +#define _LTTNG_KERNEL_VERSION_H > + > +/* > + * lttng-events.h > + * > + * Contains helpers to check more complex kernel version conditions. > + * > + * Copyright (C) 2012 Mathieu Desnoyers > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; only > + * version 2.1 of the License. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA > + */ > + > +#include > + > +/* > + * This macro checks if the kernel version is between the two specified > + * versions. > + */ > +#define LTTNG_KERNEL_RANGE(a_low, b_low, c_low, a_high, b_high, c_high) \ > + (LINUX_VERSION_CODE >= KERNEL_VERSION(a_low, b_low, c_low) && \ > + LINUX_VERSION_CODE <= KERNEL_VERSION(a_high, b_high, c_high)) > + > +#endif /* _LTTNG_KERNEL_VERSION_H */ > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From simon.marchi at polymtl.ca Fri Nov 23 17:54:40 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 23 Nov 2012 17:54:40 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix compilation for 3.0 kernels that are named 2.6.40 Message-ID: <1353711280-8395-1-git-send-email-simon.marchi@polymtl.ca> Since some distro released the 3.0 kernel as 2.6.40, it might be useful to adjust some checks to treat 2.6.40 kernels as 3.0. Signed-off-by: Simon Marchi --- instrumentation/events/lttng-module/net.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h index a444b07..e552cf7 100644 --- a/instrumentation/events/lttng-module/net.h +++ b/instrumentation/events/lttng-module/net.h @@ -12,7 +12,7 @@ TRACE_EVENT(net_dev_xmit, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) TP_PROTO(struct sk_buff *skb, int rc, struct net_device *dev, @@ -30,14 +30,14 @@ TRACE_EVENT(net_dev_xmit, __field( void *, skbaddr ) __field( unsigned int, len ) __field( int, rc ) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) __string( name, dev->name ) #else __string( name, skb->dev->name ) #endif ), -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) TP_fast_assign( tp_assign(skbaddr, skb) tp_assign(len, skb_len) -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 23 17:56:08 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 23 Nov 2012 17:56:08 -0500 Subject: [lttng-dev] [PATCH lttng-modules 1/2] Fix compilation for 3.0 branch (>= 3.0.39). Message-ID: <1353711369-8449-1-git-send-email-simon.marchi@polymtl.ca> The isolate_mode_t type that appeared in 3.2 was backported to 3.0.39 so the version check must be fixed. It was not backported to the 3.1 branch though, so it must be excluded. Signed-off-by: Simon Marchi --- probes/lttng-probe-vmscan.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c index 2abd0e4..0205c7e 100644 --- a/probes/lttng-probe-vmscan.c +++ b/probes/lttng-probe-vmscan.c @@ -30,6 +30,8 @@ */ #include +#include "../lttng-kernel-version.h" + /* * Create LTTng tracepoint probes. */ @@ -37,7 +39,8 @@ #define CREATE_TRACE_POINTS #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ + LTTNG_KERNEL_RANGE(3,1,0, 3,1,10) typedef int isolate_mode_t; #endif -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 23 17:56:09 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 23 Nov 2012 17:56:09 -0500 Subject: [lttng-dev] [PATCH lttng-modules 2/2] Fix compilation for 3.0 kernels that are named 2.6.40 In-Reply-To: <1353711369-8449-1-git-send-email-simon.marchi@polymtl.ca> References: <1353711369-8449-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <1353711369-8449-2-git-send-email-simon.marchi@polymtl.ca> Since some distro released the 3.0 kernel as 2.6.40, it might be useful to adjust some checks to treat 2.6.40 kernels as 3.0. Signed-off-by: Simon Marchi --- instrumentation/events/lttng-module/net.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h index a444b07..e552cf7 100644 --- a/instrumentation/events/lttng-module/net.h +++ b/instrumentation/events/lttng-module/net.h @@ -12,7 +12,7 @@ TRACE_EVENT(net_dev_xmit, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) TP_PROTO(struct sk_buff *skb, int rc, struct net_device *dev, @@ -30,14 +30,14 @@ TRACE_EVENT(net_dev_xmit, __field( void *, skbaddr ) __field( unsigned int, len ) __field( int, rc ) -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) __string( name, dev->name ) #else __string( name, skb->dev->name ) #endif ), -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) TP_fast_assign( tp_assign(skbaddr, skb) tp_assign(len, skb_len) -- 1.7.1 From simon.marchi at polymtl.ca Fri Nov 23 17:56:05 2012 From: simon.marchi at polymtl.ca (Simon Marchi) Date: Fri, 23 Nov 2012 17:56:05 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Fix compilation for 3.0 kernels that are named 2.6.40 In-Reply-To: <1353711280-8395-1-git-send-email-simon.marchi@polymtl.ca> References: <1353711280-8395-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: Please ignore, I sent only this one patch instead of the two I intended. On Fri, Nov 23, 2012 at 5:54 PM, Simon Marchi wrote: > Since some distro released the 3.0 kernel as 2.6.40, it might be useful > to adjust some checks to treat 2.6.40 kernels as 3.0. > > Signed-off-by: Simon Marchi > --- > instrumentation/events/lttng-module/net.h | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h > index a444b07..e552cf7 100644 > --- a/instrumentation/events/lttng-module/net.h > +++ b/instrumentation/events/lttng-module/net.h > @@ -12,7 +12,7 @@ > > TRACE_EVENT(net_dev_xmit, > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > TP_PROTO(struct sk_buff *skb, > int rc, > struct net_device *dev, > @@ -30,14 +30,14 @@ TRACE_EVENT(net_dev_xmit, > __field( void *, skbaddr ) > __field( unsigned int, len ) > __field( int, rc ) > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > __string( name, dev->name ) > #else > __string( name, skb->dev->name ) > #endif > ), > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > TP_fast_assign( > tp_assign(skbaddr, skb) > tp_assign(len, skb_len) > -- > 1.7.1 > From mathieu.desnoyers at efficios.com Fri Nov 23 18:12:04 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 23 Nov 2012 18:12:04 -0500 Subject: [lttng-dev] [PATCH lttng-modules 1/2] Fix compilation for 3.0 branch (>= 3.0.39). In-Reply-To: <1353711369-8449-1-git-send-email-simon.marchi@polymtl.ca> References: <1353711369-8449-1-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121123231203.GA15053@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > The isolate_mode_t type that appeared in 3.2 was backported to 3.0.39 so > the version check must be fixed. It was not backported to the 3.1 branch > though, so it must be excluded. Merged, thanks! Mathieu > > Signed-off-by: Simon Marchi > --- > probes/lttng-probe-vmscan.c | 5 ++++- > 1 files changed, 4 insertions(+), 1 deletions(-) > > diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c > index 2abd0e4..0205c7e 100644 > --- a/probes/lttng-probe-vmscan.c > +++ b/probes/lttng-probe-vmscan.c > @@ -30,6 +30,8 @@ > */ > #include > > +#include "../lttng-kernel-version.h" > + > /* > * Create LTTng tracepoint probes. > */ > @@ -37,7 +39,8 @@ > #define CREATE_TRACE_POINTS > #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > > -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) > +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ > + LTTNG_KERNEL_RANGE(3,1,0, 3,1,10) > typedef int isolate_mode_t; > #endif > > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Fri Nov 23 18:12:22 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Fri, 23 Nov 2012 18:12:22 -0500 Subject: [lttng-dev] [PATCH lttng-modules 2/2] Fix compilation for 3.0 kernels that are named 2.6.40 In-Reply-To: <1353711369-8449-2-git-send-email-simon.marchi@polymtl.ca> References: <1353711369-8449-1-git-send-email-simon.marchi@polymtl.ca> <1353711369-8449-2-git-send-email-simon.marchi@polymtl.ca> Message-ID: <20121123231222.GA15132@Krystal> * Simon Marchi (simon.marchi at polymtl.ca) wrote: > Since some distro released the 3.0 kernel as 2.6.40, it might be useful > to adjust some checks to treat 2.6.40 kernels as 3.0. merged, thanks! Mathieu > > Signed-off-by: Simon Marchi > --- > instrumentation/events/lttng-module/net.h | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/instrumentation/events/lttng-module/net.h b/instrumentation/events/lttng-module/net.h > index a444b07..e552cf7 100644 > --- a/instrumentation/events/lttng-module/net.h > +++ b/instrumentation/events/lttng-module/net.h > @@ -12,7 +12,7 @@ > > TRACE_EVENT(net_dev_xmit, > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > TP_PROTO(struct sk_buff *skb, > int rc, > struct net_device *dev, > @@ -30,14 +30,14 @@ TRACE_EVENT(net_dev_xmit, > __field( void *, skbaddr ) > __field( unsigned int, len ) > __field( int, rc ) > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > __string( name, dev->name ) > #else > __string( name, skb->dev->name ) > #endif > ), > > -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,40)) > TP_fast_assign( > tp_assign(skbaddr, skb) > tp_assign(len, skb_len) > -- > 1.7.1 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From andrew_gabbasov at mentor.com Sun Nov 25 14:27:10 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Sun, 25 Nov 2012 13:27:10 -0600 Subject: [lttng-dev] [PATCH] Remove remaining semicolons in TP_fast_assign blocks Message-ID: <1353871630-19756-1-git-send-email-andrew_gabbasov@mentor.com> Signed-off-by: Andrew Gabbasov --- instrumentation/events/lttng-module/jbd2.h | 22 +++++++++++----------- instrumentation/events/lttng-module/sock.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h index 91e2e6c..c7992c0 100644 --- a/instrumentation/events/lttng-module/jbd2.h +++ b/instrumentation/events/lttng-module/jbd2.h @@ -25,8 +25,8 @@ TRACE_EVENT(jbd2_checkpoint, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(result, result); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(result, result) ), TP_printk("dev %d,%d result %d", @@ -46,9 +46,9 @@ DECLARE_EVENT_CLASS(jbd2_commit, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); - tp_assign(transaction, commit_transaction->t_tid); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) + tp_assign(transaction, commit_transaction->t_tid) ), TP_printk("dev %d,%d transaction %d sync %d", @@ -97,10 +97,10 @@ TRACE_EVENT(jbd2_end_commit, ), TP_fast_assign( - tp_assign(dev, journal->j_fs_dev->bd_dev); - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); - tp_assign(transaction, commit_transaction->t_tid); - tp_assign(head, journal->j_tail_sequence); + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) + tp_assign(transaction, commit_transaction->t_tid) + tp_assign(head, journal->j_tail_sequence) ), TP_printk("dev %d,%d transaction %d sync %d head %d", @@ -119,8 +119,8 @@ TRACE_EVENT(jbd2_submit_inode_data, ), TP_fast_assign( - tp_assign(dev, inode->i_sb->s_dev); - tp_assign(ino, inode->i_ino); + tp_assign(dev, inode->i_sb->s_dev) + tp_assign(ino, inode->i_ino) ), TP_printk("dev %d,%d ino %lu", diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h index c4e689a..b0c7411 100644 --- a/instrumentation/events/lttng-module/sock.h +++ b/instrumentation/events/lttng-module/sock.h @@ -48,7 +48,7 @@ TRACE_EVENT(sock_exceed_buf_limit, tp_assign(sysctl_mem, prot->sysctl_mem) tp_assign(allocated, allocated) tp_assign(sysctl_rmem, prot->sysctl_rmem[0]) - tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)) ), TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " -- 1.7.10.4 From andrew_gabbasov at mentor.com Sun Nov 25 14:39:14 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Sun, 25 Nov 2012 13:39:14 -0600 Subject: [lttng-dev] [PATCH lttng-modules] sched instrumentation: rename "pid" fields in sched_process_exec Message-ID: <1353872354-19886-1-git-send-email-andrew_gabbasov@mentor.com> Rename "pid" to "tid" fields in new code, similarly to what was done earlier for all sched tracepoints. Signed-off-by: Andrew Gabbasov --- instrumentation/events/lttng-module/sched.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/instrumentation/events/lttng-module/sched.h b/instrumentation/events/lttng-module/sched.h index ca46ed0..005f3d1 100644 --- a/instrumentation/events/lttng-module/sched.h +++ b/instrumentation/events/lttng-module/sched.h @@ -326,18 +326,18 @@ TRACE_EVENT(sched_process_exec, TP_STRUCT__entry( __string( filename, bprm->filename ) - __field( pid_t, pid ) - __field( pid_t, old_pid ) + __field( pid_t, tid ) + __field( pid_t, old_tid ) ), TP_fast_assign( tp_strcpy(filename, bprm->filename) - tp_assign(pid, p->pid) - tp_assign(old_pid, old_pid) + tp_assign(tid, p->pid) + tp_assign(old_tid, old_pid) ), - TP_printk("filename=%s pid=%d old_pid=%d", __get_str(filename), - __entry->pid, __entry->old_pid) + TP_printk("filename=%s tid=%d old_tid=%d", __get_str(filename), + __entry->tid, __entry->old_tid) ) #endif -- 1.7.10.4 From andrew_gabbasov at mentor.com Sun Nov 25 14:40:00 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Sun, 25 Nov 2012 13:40:00 -0600 Subject: [lttng-dev] [PATCH lttng-modules] ext3 instrumentation: fix of assignment code conversion Message-ID: <1353872400-19927-1-git-send-email-andrew_gabbasov@mentor.com> Due to specifics of handling assignment code in lttng-modules, plain code in TP_fast_assign (outside tp_* macros) will not be reached. Everything should be enclosed into tp_* fragments. Signed-off-by: Andrew Gabbasov --- instrumentation/events/lttng-module/ext3.h | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h index de80df9..f1b4aa9 100644 --- a/instrumentation/events/lttng-module/ext3.h +++ b/instrumentation/events/lttng-module/ext3.h @@ -6,12 +6,6 @@ #include -#ifndef _TRACE_EXT3_DEF -#define _TRACE_EXT3_DEF -static struct dentry *dentry; -#endif - - TRACE_EVENT(ext3_free_inode, TP_PROTO(struct inode *inode), @@ -441,12 +435,10 @@ TRACE_EVENT(ext3_sync_file_enter, ), TP_fast_assign( - dentry = file->f_path.dentry; - - tp_assign(dev, dentry->d_inode->i_sb->s_dev) - tp_assign(ino, dentry->d_inode->i_ino) + tp_assign(dev, file->f_path.dentry->d_inode->i_sb->s_dev) + tp_assign(ino, file->f_path.dentry->d_inode->i_ino) tp_assign(datasync, datasync) - tp_assign(parent, dentry->d_parent->d_inode->i_ino) + tp_assign(parent, file->f_path.dentry->d_parent->d_inode->i_ino) ), TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", -- 1.7.10.4 From andrew_gabbasov at mentor.com Sun Nov 25 14:41:42 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Sun, 25 Nov 2012 13:41:42 -0600 Subject: [lttng-dev] [PATCH lttng-modules] sock instrumentation: fix fields to get referenced values Message-ID: <1353872502-19968-1-git-send-email-andrew_gabbasov@mentor.com> Due to specific of passing values in lttng-modules, if it is supposed to display the values, passing a pointer will not be enough, we need to store the actual values. Signed-off-by: Andrew Gabbasov --- instrumentation/events/lttng-module/sock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h index b0c7411..3e3dbc7 100644 --- a/instrumentation/events/lttng-module/sock.h +++ b/instrumentation/events/lttng-module/sock.h @@ -37,7 +37,7 @@ TRACE_EVENT(sock_exceed_buf_limit, TP_STRUCT__entry( __string(name, prot->name) - __field(long *, sysctl_mem) + __array(long, sysctl_mem, 3) __field(long, allocated) __field(int, sysctl_rmem) __field(int, rmem_alloc) @@ -45,7 +45,7 @@ TRACE_EVENT(sock_exceed_buf_limit, TP_fast_assign( tp_strcpy(name, prot->name) - tp_assign(sysctl_mem, prot->sysctl_mem) + tp_memcpy(sysctl_mem, prot->sysctl_mem, 3 * sizeof(long)) tp_assign(allocated, allocated) tp_assign(sysctl_rmem, prot->sysctl_rmem[0]) tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)) -- 1.7.10.4 From mathieu.desnoyers at efficios.com Sun Nov 25 16:14:26 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 25 Nov 2012 16:14:26 -0500 Subject: [lttng-dev] [PATCH] Remove remaining semicolons in TP_fast_assign blocks In-Reply-To: <1353871630-19756-1-git-send-email-andrew_gabbasov@mentor.com> References: <1353871630-19756-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121125211426.GA13672@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > Signed-off-by: Andrew Gabbasov Merged, thanks! Mathieu > --- > instrumentation/events/lttng-module/jbd2.h | 22 +++++++++++----------- > instrumentation/events/lttng-module/sock.h | 2 +- > 2 files changed, 12 insertions(+), 12 deletions(-) > > diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h > index 91e2e6c..c7992c0 100644 > --- a/instrumentation/events/lttng-module/jbd2.h > +++ b/instrumentation/events/lttng-module/jbd2.h > @@ -25,8 +25,8 @@ TRACE_EVENT(jbd2_checkpoint, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(result, result); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(result, result) > ), > > TP_printk("dev %d,%d result %d", > @@ -46,9 +46,9 @@ DECLARE_EVENT_CLASS(jbd2_commit, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > - tp_assign(transaction, commit_transaction->t_tid); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) > + tp_assign(transaction, commit_transaction->t_tid) > ), > > TP_printk("dev %d,%d transaction %d sync %d", > @@ -97,10 +97,10 @@ TRACE_EVENT(jbd2_end_commit, > ), > > TP_fast_assign( > - tp_assign(dev, journal->j_fs_dev->bd_dev); > - tp_assign(sync_commit, commit_transaction->t_synchronous_commit); > - tp_assign(transaction, commit_transaction->t_tid); > - tp_assign(head, journal->j_tail_sequence); > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(sync_commit, commit_transaction->t_synchronous_commit) > + tp_assign(transaction, commit_transaction->t_tid) > + tp_assign(head, journal->j_tail_sequence) > ), > > TP_printk("dev %d,%d transaction %d sync %d head %d", > @@ -119,8 +119,8 @@ TRACE_EVENT(jbd2_submit_inode_data, > ), > > TP_fast_assign( > - tp_assign(dev, inode->i_sb->s_dev); > - tp_assign(ino, inode->i_ino); > + tp_assign(dev, inode->i_sb->s_dev) > + tp_assign(ino, inode->i_ino) > ), > > TP_printk("dev %d,%d ino %lu", > diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h > index c4e689a..b0c7411 100644 > --- a/instrumentation/events/lttng-module/sock.h > +++ b/instrumentation/events/lttng-module/sock.h > @@ -48,7 +48,7 @@ TRACE_EVENT(sock_exceed_buf_limit, > tp_assign(sysctl_mem, prot->sysctl_mem) > tp_assign(allocated, allocated) > tp_assign(sysctl_rmem, prot->sysctl_rmem[0]) > - tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)); > + tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)) > ), > > TP_printk("proto:%s sysctl_mem=%ld,%ld,%ld allocated=%ld " > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Nov 25 16:14:35 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 25 Nov 2012 16:14:35 -0500 Subject: [lttng-dev] [PATCH lttng-modules] sched instrumentation: rename "pid" fields in sched_process_exec In-Reply-To: <1353872354-19886-1-git-send-email-andrew_gabbasov@mentor.com> References: <1353872354-19886-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121125211435.GB13672@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > Rename "pid" to "tid" fields in new code, similarly to what was > done earlier for all sched tracepoints. > > Signed-off-by: Andrew Gabbasov Merged, thanks! Mathieu > --- > instrumentation/events/lttng-module/sched.h | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/instrumentation/events/lttng-module/sched.h b/instrumentation/events/lttng-module/sched.h > index ca46ed0..005f3d1 100644 > --- a/instrumentation/events/lttng-module/sched.h > +++ b/instrumentation/events/lttng-module/sched.h > @@ -326,18 +326,18 @@ TRACE_EVENT(sched_process_exec, > > TP_STRUCT__entry( > __string( filename, bprm->filename ) > - __field( pid_t, pid ) > - __field( pid_t, old_pid ) > + __field( pid_t, tid ) > + __field( pid_t, old_tid ) > ), > > TP_fast_assign( > tp_strcpy(filename, bprm->filename) > - tp_assign(pid, p->pid) > - tp_assign(old_pid, old_pid) > + tp_assign(tid, p->pid) > + tp_assign(old_tid, old_pid) > ), > > - TP_printk("filename=%s pid=%d old_pid=%d", __get_str(filename), > - __entry->pid, __entry->old_pid) > + TP_printk("filename=%s tid=%d old_tid=%d", __get_str(filename), > + __entry->tid, __entry->old_tid) > ) > #endif > > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Nov 25 16:14:45 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 25 Nov 2012 16:14:45 -0500 Subject: [lttng-dev] [PATCH lttng-modules] ext3 instrumentation: fix of assignment code conversion In-Reply-To: <1353872400-19927-1-git-send-email-andrew_gabbasov@mentor.com> References: <1353872400-19927-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121125211445.GC13672@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > Due to specifics of handling assignment code in lttng-modules, > plain code in TP_fast_assign (outside tp_* macros) will not be reached. > Everything should be enclosed into tp_* fragments. > > Signed-off-by: Andrew Gabbasov Merged, thanks! Mathieu > --- > instrumentation/events/lttng-module/ext3.h | 14 +++----------- > 1 file changed, 3 insertions(+), 11 deletions(-) > > diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h > index de80df9..f1b4aa9 100644 > --- a/instrumentation/events/lttng-module/ext3.h > +++ b/instrumentation/events/lttng-module/ext3.h > @@ -6,12 +6,6 @@ > > #include > > -#ifndef _TRACE_EXT3_DEF > -#define _TRACE_EXT3_DEF > -static struct dentry *dentry; > -#endif > - > - > TRACE_EVENT(ext3_free_inode, > TP_PROTO(struct inode *inode), > > @@ -441,12 +435,10 @@ TRACE_EVENT(ext3_sync_file_enter, > ), > > TP_fast_assign( > - dentry = file->f_path.dentry; > - > - tp_assign(dev, dentry->d_inode->i_sb->s_dev) > - tp_assign(ino, dentry->d_inode->i_ino) > + tp_assign(dev, file->f_path.dentry->d_inode->i_sb->s_dev) > + tp_assign(ino, file->f_path.dentry->d_inode->i_ino) > tp_assign(datasync, datasync) > - tp_assign(parent, dentry->d_parent->d_inode->i_ino) > + tp_assign(parent, file->f_path.dentry->d_parent->d_inode->i_ino) > ), > > TP_printk("dev %d,%d ino %lu parent %ld datasync %d ", > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Nov 25 16:14:54 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 25 Nov 2012 16:14:54 -0500 Subject: [lttng-dev] [PATCH lttng-modules] sock instrumentation: fix fields to get referenced values In-Reply-To: <1353872502-19968-1-git-send-email-andrew_gabbasov@mentor.com> References: <1353872502-19968-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121125211453.GD13672@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > Due to specific of passing values in lttng-modules, if it is supposed > to display the values, passing a pointer will not be enough, > we need to store the actual values. > > Signed-off-by: Andrew Gabbasov Merged, thanks! Mathieu > --- > instrumentation/events/lttng-module/sock.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/instrumentation/events/lttng-module/sock.h b/instrumentation/events/lttng-module/sock.h > index b0c7411..3e3dbc7 100644 > --- a/instrumentation/events/lttng-module/sock.h > +++ b/instrumentation/events/lttng-module/sock.h > @@ -37,7 +37,7 @@ TRACE_EVENT(sock_exceed_buf_limit, > > TP_STRUCT__entry( > __string(name, prot->name) > - __field(long *, sysctl_mem) > + __array(long, sysctl_mem, 3) > __field(long, allocated) > __field(int, sysctl_rmem) > __field(int, rmem_alloc) > @@ -45,7 +45,7 @@ TRACE_EVENT(sock_exceed_buf_limit, > > TP_fast_assign( > tp_strcpy(name, prot->name) > - tp_assign(sysctl_mem, prot->sysctl_mem) > + tp_memcpy(sysctl_mem, prot->sysctl_mem, 3 * sizeof(long)) > tp_assign(allocated, allocated) > tp_assign(sysctl_rmem, prot->sysctl_rmem[0]) > tp_assign(rmem_alloc, atomic_read(&sk->sk_rmem_alloc)) > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Nov 25 22:22:20 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 25 Nov 2012 22:22:20 -0500 Subject: [lttng-dev] [PATCH] urcu-mb/signal/membarrier: batch concurrent synchronize_rcu() Message-ID: <20121126032220.GA19034@Krystal> Here are benchmarks on batching of synchronize_rcu(), and it leads to very interesting scalability improvement and speedups, e.g., on a 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater threads, each updater using synchronize_rcu()): * Serialized grace periods: ./test_urcu 4 20 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 714598368 nr_writes 5032889 nr_ops 719631257 * Batched grace periods: ./test_urcu 4 20 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 611848168 nr_writes 9877965 nr_ops 621726133 For a 9877965/5032889 = 1.96 speedup for 20 updaters. Of course, we can see that readers have slowed down, probably due to increased update traffic, given there is no change to the read-side code whatsoever. Now let's see the penality of managing the stack for single-updater. With 4 readers, single updater: * Serialized grace periods : ./test_urcu 4 1 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 241959144 nr_writes 11146189 nr_ops 253105333 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 257131080 nr_writes 12310537 nr_ops 269441617 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 259973359 nr_writes 12203025 nr_ops 272176384 * Batched grace periods : SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 298926555 nr_writes 14018748 nr_ops 312945303 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 272411290 nr_writes 12832166 nr_ops 285243456 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 267511858 nr_writes 12822026 nr_ops 280333884 Serialized vs batched seems to similar, batched possibly even slightly faster, but this is probably caused by NUMA affinity. CC: Paul E. McKenney CC: Lai Jiangshan CC: Alan Stern Signed-off-by: Mathieu Desnoyers --- diff --git a/urcu.c b/urcu.c index e6ff0f3..836bad9 100644 --- a/urcu.c +++ b/urcu.c @@ -43,6 +43,7 @@ #include "urcu/tls-compat.h" #include "urcu-die.h" +#include "urcu-wait.h" /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ #undef _LGPL_SOURCE @@ -106,6 +107,12 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); static CDS_LIST_HEAD(registry); +/* + * Queue keeping threads awaiting to wait for a grace period. Contains + * struct gp_waiters_thread objects. + */ +static DEFINE_URCU_WAIT_QUEUE(gp_waiters); + static void mutex_lock(pthread_mutex_t *mutex) { int ret; @@ -306,9 +313,31 @@ void synchronize_rcu(void) { CDS_LIST_HEAD(cur_snap_readers); CDS_LIST_HEAD(qsreaders); + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); + struct urcu_waiters waiters; + + /* + * Add ourself to gp_waiters queue of threads awaiting to wait + * for a grace period. Proceed to perform the grace period only + * if we are the first thread added into the queue. + */ + if (urcu_wait_add(&gp_waiters, &wait) != 0) { + /* Not first in queue: will be awakened by another thread. */ + urcu_adaptative_busy_wait(&wait); + /* Order following memory accesses after grace period. */ + cmm_smp_mb(); + return; + } + /* We won't need to wake ourself up */ + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); mutex_lock(&rcu_gp_lock); + /* + * Move all waiters into our local queue. + */ + urcu_move_waiters(&waiters, &gp_waiters); + if (cds_list_empty(®istry)) goto out; @@ -374,6 +403,13 @@ void synchronize_rcu(void) smp_mb_master(RCU_MB_GROUP); out: mutex_unlock(&rcu_gp_lock); + + /* + * Wakeup waiters only after we have completed the grace period + * and have ensured the memory barriers at the end of the grace + * period have been issued. + */ + urcu_wake_all_waiters(&waiters); } /* -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Sun Nov 25 22:32:17 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Sun, 25 Nov 2012 22:32:17 -0500 Subject: [lttng-dev] [PATCH] urcu-mb/signal/membarrier: batch concurrent synchronize_rcu() In-Reply-To: <20121126032220.GA19034@Krystal> References: <20121126032220.GA19034@Krystal> Message-ID: <20121126033217.GA19396@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > Here are benchmarks on batching of synchronize_rcu(), and it leads to > very interesting scalability improvement and speedups, e.g., on a > 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > threads, each updater using synchronize_rcu()): > > * Serialized grace periods: > ./test_urcu 4 20 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 714598368 nr_writes 5032889 nr_ops 719631257 > > * Batched grace periods: > > ./test_urcu 4 20 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 611848168 nr_writes 9877965 nr_ops 621726133 > > For a 9877965/5032889 = 1.96 speedup for 20 updaters. > > Of course, we can see that readers have slowed down, probably due to > increased update traffic, given there is no change to the read-side code > whatsoever. > > Now let's see the penality of managing the stack for single-updater. > With 4 readers, single updater: > > * Serialized grace periods : > > ./test_urcu 4 1 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 241959144 nr_writes 11146189 nr_ops 253105333 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 257131080 nr_writes 12310537 nr_ops 269441617 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 259973359 nr_writes 12203025 nr_ops 272176384 > > * Batched grace periods : > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 298926555 nr_writes 14018748 nr_ops 312945303 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 272411290 nr_writes 12832166 nr_ops 285243456 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 267511858 nr_writes 12822026 nr_ops 280333884 > > Serialized vs batched seems to similar, batched possibly even slightly > faster, but this is probably caused by NUMA affinity. > > CC: Paul E. McKenney > CC: Lai Jiangshan > CC: Alan Stern > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/urcu.c b/urcu.c > index e6ff0f3..836bad9 100644 > --- a/urcu.c > +++ b/urcu.c > @@ -43,6 +43,7 @@ > #include "urcu/tls-compat.h" > > #include "urcu-die.h" > +#include "urcu-wait.h" > > /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > #undef _LGPL_SOURCE > @@ -106,6 +107,12 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > > static CDS_LIST_HEAD(registry); > > +/* > + * Queue keeping threads awaiting to wait for a grace period. Contains > + * struct gp_waiters_thread objects. > + */ > +static DEFINE_URCU_WAIT_QUEUE(gp_waiters); > + > static void mutex_lock(pthread_mutex_t *mutex) > { > int ret; > @@ -306,9 +313,31 @@ void synchronize_rcu(void) > { > CDS_LIST_HEAD(cur_snap_readers); > CDS_LIST_HEAD(qsreaders); > + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); > + struct urcu_waiters waiters; > + > + /* > + * Add ourself to gp_waiters queue of threads awaiting to wait > + * for a grace period. Proceed to perform the grace period only > + * if we are the first thread added into the queue. > + */ > + if (urcu_wait_add(&gp_waiters, &wait) != 0) { Actually, we're missing a memory barrier right here. Here is what I'm adding right away: + /* Order previous memory accesses before grace period. */ + cmm_smp_mb(); Thanks, Mathieu > + /* Not first in queue: will be awakened by another thread. */ > + urcu_adaptative_busy_wait(&wait); > + /* Order following memory accesses after grace period. */ > + cmm_smp_mb(); > + return; > + } > + /* We won't need to wake ourself up */ > + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); > > mutex_lock(&rcu_gp_lock); > > + /* > + * Move all waiters into our local queue. > + */ > + urcu_move_waiters(&waiters, &gp_waiters); > + > if (cds_list_empty(®istry)) > goto out; > > @@ -374,6 +403,13 @@ void synchronize_rcu(void) > smp_mb_master(RCU_MB_GROUP); > out: > mutex_unlock(&rcu_gp_lock); > + > + /* > + * Wakeup waiters only after we have completed the grace period > + * and have ensured the memory barriers at the end of the grace > + * period have been issued. > + */ > + urcu_wake_all_waiters(&waiters); > } > > /* > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From laijs at cn.fujitsu.com Sun Nov 25 22:47:06 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Mon, 26 Nov 2012 11:47:06 +0800 Subject: [lttng-dev] [PATCH] urcu-mb/signal/membarrier: batch concurrent synchronize_rcu() In-Reply-To: <20121126032220.GA19034@Krystal> References: <20121126032220.GA19034@Krystal> Message-ID: <50B2E63A.3020000@cn.fujitsu.com> I'm also interesting in the result of: ./test_urcu 12 12 20 ./test_urcu 16 8 20 ./test_urcu 20 4 20 On 11/26/2012 11:22 AM, Mathieu Desnoyers wrote: > Here are benchmarks on batching of synchronize_rcu(), and it leads to > very interesting scalability improvement and speedups, e.g., on a > 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > threads, each updater using synchronize_rcu()): > > * Serialized grace periods: > ./test_urcu 4 20 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 714598368 nr_writes 5032889 nr_ops 719631257 > > * Batched grace periods: > > ./test_urcu 4 20 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 611848168 nr_writes 9877965 nr_ops 621726133 > > For a 9877965/5032889 = 1.96 speedup for 20 updaters. > > Of course, we can see that readers have slowed down, probably due to > increased update traffic, given there is no change to the read-side code > whatsoever. > > Now let's see the penality of managing the stack for single-updater. > With 4 readers, single updater: > > * Serialized grace periods : > > ./test_urcu 4 1 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 241959144 nr_writes 11146189 nr_ops 253105333 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 257131080 nr_writes 12310537 nr_ops 269441617 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 259973359 nr_writes 12203025 nr_ops 272176384 > > * Batched grace periods : > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 298926555 nr_writes 14018748 nr_ops 312945303 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 272411290 nr_writes 12832166 nr_ops 285243456 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 267511858 nr_writes 12822026 nr_ops 280333884 > > Serialized vs batched seems to similar, batched possibly even slightly > faster, but this is probably caused by NUMA affinity. > > CC: Paul E. McKenney > CC: Lai Jiangshan > CC: Alan Stern > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/urcu.c b/urcu.c > index e6ff0f3..836bad9 100644 > --- a/urcu.c > +++ b/urcu.c > @@ -43,6 +43,7 @@ > #include "urcu/tls-compat.h" > > #include "urcu-die.h" > +#include "urcu-wait.h" > > /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > #undef _LGPL_SOURCE > @@ -106,6 +107,12 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > > static CDS_LIST_HEAD(registry); > > +/* > + * Queue keeping threads awaiting to wait for a grace period. Contains > + * struct gp_waiters_thread objects. > + */ > +static DEFINE_URCU_WAIT_QUEUE(gp_waiters); > + > static void mutex_lock(pthread_mutex_t *mutex) > { > int ret; > @@ -306,9 +313,31 @@ void synchronize_rcu(void) > { > CDS_LIST_HEAD(cur_snap_readers); > CDS_LIST_HEAD(qsreaders); > + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); > + struct urcu_waiters waiters; > + > + /* > + * Add ourself to gp_waiters queue of threads awaiting to wait > + * for a grace period. Proceed to perform the grace period only > + * if we are the first thread added into the queue. > + */ > + if (urcu_wait_add(&gp_waiters, &wait) != 0) { > + /* Not first in queue: will be awakened by another thread. */ > + urcu_adaptative_busy_wait(&wait); > + /* Order following memory accesses after grace period. */ > + cmm_smp_mb(); > + return; > + } > + /* We won't need to wake ourself up */ > + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); > > mutex_lock(&rcu_gp_lock); > > + /* > + * Move all waiters into our local queue. > + */ > + urcu_move_waiters(&waiters, &gp_waiters); > + > if (cds_list_empty(®istry)) > goto out; > > @@ -374,6 +403,13 @@ void synchronize_rcu(void) > smp_mb_master(RCU_MB_GROUP); > out: > mutex_unlock(&rcu_gp_lock); > + > + /* > + * Wakeup waiters only after we have completed the grace period > + * and have ensured the memory barriers at the end of the grace > + * period have been issued. > + */ > + urcu_wake_all_waiters(&waiters); > } > > /* > From laijs at cn.fujitsu.com Sun Nov 25 22:58:51 2012 From: laijs at cn.fujitsu.com (Lai Jiangshan) Date: Mon, 26 Nov 2012 11:58:51 +0800 Subject: [lttng-dev] [PATCH] urcu-mb/signal/membarrier: batch concurrent synchronize_rcu() In-Reply-To: <20121126032220.GA19034@Krystal> References: <20121126032220.GA19034@Krystal> Message-ID: <50B2E8FB.4000906@cn.fujitsu.com> On 11/26/2012 11:22 AM, Mathieu Desnoyers wrote: > Here are benchmarks on batching of synchronize_rcu(), and it leads to > very interesting scalability improvement and speedups, e.g., on a > 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > threads, each updater using synchronize_rcu()): > > * Serialized grace periods: > ./test_urcu 4 20 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 714598368 nr_writes 5032889 nr_ops 719631257 > > * Batched grace periods: > > ./test_urcu 4 20 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 20 wdelay 0 > nr_reads 611848168 nr_writes 9877965 nr_ops 621726133 > > For a 9877965/5032889 = 1.96 speedup for 20 updaters. I guess it is the result of RCU_MB, (if it does, could you test RCU_SIGNAL, it may speedup more) > > Of course, we can see that readers have slowed down, probably due to > increased update traffic, given there is no change to the read-side code > whatsoever. > > Now let's see the penality of managing the stack for single-updater. > With 4 readers, single updater: > > * Serialized grace periods : > > ./test_urcu 4 1 20 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 241959144 nr_writes 11146189 nr_ops 253105333 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 257131080 nr_writes 12310537 nr_ops 269441617 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 259973359 nr_writes 12203025 nr_ops 272176384 > > * Batched grace periods : > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 298926555 nr_writes 14018748 nr_ops 312945303 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 272411290 nr_writes 12832166 nr_ops 285243456 > SUMMARY ./test_urcu testdur 20 nr_readers 4 > rdur 0 wdur 0 nr_writers 1 wdelay 0 > nr_reads 267511858 nr_writes 12822026 nr_ops 280333884 > > Serialized vs batched seems to similar, batched possibly even slightly > faster, but this is probably caused by NUMA affinity. > > CC: Paul E. McKenney > CC: Lai Jiangshan > CC: Alan Stern > Signed-off-by: Mathieu Desnoyers > --- > diff --git a/urcu.c b/urcu.c > index e6ff0f3..836bad9 100644 > --- a/urcu.c > +++ b/urcu.c > @@ -43,6 +43,7 @@ > #include "urcu/tls-compat.h" > > #include "urcu-die.h" > +#include "urcu-wait.h" > > /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > #undef _LGPL_SOURCE > @@ -106,6 +107,12 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > > static CDS_LIST_HEAD(registry); > > +/* > + * Queue keeping threads awaiting to wait for a grace period. Contains > + * struct gp_waiters_thread objects. > + */ > +static DEFINE_URCU_WAIT_QUEUE(gp_waiters); > + > static void mutex_lock(pthread_mutex_t *mutex) > { > int ret; > @@ -306,9 +313,31 @@ void synchronize_rcu(void) > { > CDS_LIST_HEAD(cur_snap_readers); > CDS_LIST_HEAD(qsreaders); > + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); > + struct urcu_waiters waiters; > + > + /* > + * Add ourself to gp_waiters queue of threads awaiting to wait > + * for a grace period. Proceed to perform the grace period only > + * if we are the first thread added into the queue. > + */ > + if (urcu_wait_add(&gp_waiters, &wait) != 0) { > + /* Not first in queue: will be awakened by another thread. */ > + urcu_adaptative_busy_wait(&wait); > + /* Order following memory accesses after grace period. */ > + cmm_smp_mb(); > + return; > + } > + /* We won't need to wake ourself up */ > + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); > > mutex_lock(&rcu_gp_lock); > > + /* > + * Move all waiters into our local queue. > + */ > + urcu_move_waiters(&waiters, &gp_waiters); > + > if (cds_list_empty(®istry)) > goto out; > > @@ -374,6 +403,13 @@ void synchronize_rcu(void) > smp_mb_master(RCU_MB_GROUP); > out: > mutex_unlock(&rcu_gp_lock); > + > + /* > + * Wakeup waiters only after we have completed the grace period > + * and have ensured the memory barriers at the end of the grace > + * period have been issued. > + */ > + urcu_wake_all_waiters(&waiters); > } > > /* > From David.OShea at quantum.com Mon Nov 26 03:57:09 2012 From: David.OShea at quantum.com (David OShea) Date: Mon, 26 Nov 2012 08:57:09 +0000 Subject: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust-tracepoint-event.h needs -Wsystem-headers In-Reply-To: <20121119162618.GA17428@Krystal> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> <20121119162618.GA17428@Krystal> Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F87B5C@ZURMSG1.QUANTUM.com> Hi Mathieu, Thanks for the response and apologies for the delay in mine, please see below: > -----Original Message----- > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Sent: Tuesday, 20 November 2012 2:56 AM > To: David OShea > Cc: lttng-dev at lists.lttng.org > Subject: Re: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust- > tracepoint-event.h needs -Wsystem-headers [...] > > I'm not sure if there is any way you could "fix" this so that > > -Wsystem-headers isn't required, but perhaps it would at least be > > worth documenting that this flag could be used - but perhaps not > > recommend it - to enable those checks to occur. > > I have not found any way to show those warnings from UST system headers > without -Wsystem-headers. We have the following scenario: > > probe C file > -> includes ust probe description file > -> includes tracepoint-event.h (system header) > -> includes ust probe description file > -> includes ust-tracepoint-event.h (system header) [1] > For each stage: > -> undef/define macros > -> includes ust probe description file > > Since the actual functions are created by the compiler in the scope of > ust-tracepoint-event.h [1] (a system header), the warnings are > inhibited > unless we specify -Wsystem-headers. [...] > So I guess documenting this would be the right way to do it, unless > anyone has a better idea ? I don't know much about the macros in ust-tracepoint-event.h, so this might not make any sense, but could you have the __tracepoint_provider_check_##TRACEPOINT_PROVIDER() function actually get called from the __lttng_events_init__##TRACEPOINT_PROVIDER() (constructor) function? I assume this would mean you'd get link-time errors if you have a provider name mismatch. It would also mean a lot of useless calls to empty functions at startup, but I assume that really shouldn't take too long. Perhaps this checking could be a compile-time option, so that if you're concerned about the startup time impact you can disable it, or perhaps the functions could be marked as inline? Thanks, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From David.OShea at quantum.com Mon Nov 26 04:13:01 2012 From: David.OShea at quantum.com (David OShea) Date: Mon, 26 Nov 2012 09:13:01 +0000 Subject: [lttng-dev] libust "Error: Error opening shm" every ~4 seconds if HOME variable is not set In-Reply-To: <20121030014218.GA26711@Krystal> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F843E3@ZURMSG1.QUANTUM.com> <20121030014218.GA26711@Krystal> Message-ID: <20998D40D9A2B7499CA5A3A2666CB1EB19F87B70@ZURMSG1.QUANTUM.com> Hi Mathieu, > -----Original Message----- > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > Sent: Tuesday, 30 October 2012 12:12 PM > To: David OShea > Cc: lttng-dev at lists.lttng.org > Subject: Re: [lttng-dev] libust "Error: Error opening shm" every ~4 > seconds if HOME variable is not set [...] > Thanks for reporting! Can you try with stable-2.0 branch or master > branch head ? > > Here are the commits: > > stable-2.0: > > commit e699eda9762d3cf3b0c40329eb3b6ce0947789dc > Author: Mathieu Desnoyers > Date: Mon Oct 29 21:39:42 2012 -0400 > > Cleanup: don't spawn per-user thread if HOME is not set > > Reported-by: David OShea > Signed-off-by: Mathieu Desnoyers > > master: > > commit 9ec6895c5633ed93c5acdf1e5b06f075fbd709d3 > Author: Mathieu Desnoyers > Date: Mon Oct 29 21:39:42 2012 -0400 > > Cleanup: don't spawn per-user thread if HOME is not set > > Reported-by: David OShea > Signed-off-by: Mathieu Desnoyers Thanks for that! Patching e699eda into the 2.0.5 release fixed the issue. Regards, David ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. From mathieu.desnoyers at efficios.com Mon Nov 26 09:57:35 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 09:57:35 -0500 Subject: [lttng-dev] [PATCH] urcu-mb/signal/membarrier: batch concurrent synchronize_rcu() In-Reply-To: <20121126033217.GA19396@Krystal> References: <20121126032220.GA19034@Krystal> <20121126033217.GA19396@Krystal> Message-ID: <20121126145735.GA26198@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > Here are benchmarks on batching of synchronize_rcu(), and it leads to > > very interesting scalability improvement and speedups, e.g., on a > > 24-core AMD, with a write-heavy scenario (4 readers threads, 20 updater > > threads, each updater using synchronize_rcu()): > > > > * Serialized grace periods: > > ./test_urcu 4 20 20 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 20 wdelay 0 > > nr_reads 714598368 nr_writes 5032889 nr_ops 719631257 > > > > * Batched grace periods: > > > > ./test_urcu 4 20 20 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 20 wdelay 0 > > nr_reads 611848168 nr_writes 9877965 nr_ops 621726133 > > > > For a 9877965/5032889 = 1.96 speedup for 20 updaters. > > > > Of course, we can see that readers have slowed down, probably due to > > increased update traffic, given there is no change to the read-side code > > whatsoever. > > > > Now let's see the penality of managing the stack for single-updater. > > With 4 readers, single updater: > > > > * Serialized grace periods : > > > > ./test_urcu 4 1 20 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 241959144 nr_writes 11146189 nr_ops 253105333 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 257131080 nr_writes 12310537 nr_ops 269441617 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 259973359 nr_writes 12203025 nr_ops 272176384 > > > > * Batched grace periods : > > > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 298926555 nr_writes 14018748 nr_ops 312945303 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 272411290 nr_writes 12832166 nr_ops 285243456 > > SUMMARY ./test_urcu testdur 20 nr_readers 4 > > rdur 0 wdur 0 nr_writers 1 wdelay 0 > > nr_reads 267511858 nr_writes 12822026 nr_ops 280333884 > > > > Serialized vs batched seems to similar, batched possibly even slightly > > faster, but this is probably caused by NUMA affinity. > > > > CC: Paul E. McKenney > > CC: Lai Jiangshan > > CC: Alan Stern > > Signed-off-by: Mathieu Desnoyers > > --- > > diff --git a/urcu.c b/urcu.c > > index e6ff0f3..836bad9 100644 > > --- a/urcu.c > > +++ b/urcu.c > > @@ -43,6 +43,7 @@ > > #include "urcu/tls-compat.h" > > > > #include "urcu-die.h" > > +#include "urcu-wait.h" > > > > /* Do not #define _LGPL_SOURCE to ensure we can emit the wrapper symbols */ > > #undef _LGPL_SOURCE > > @@ -106,6 +107,12 @@ DEFINE_URCU_TLS(unsigned int, rcu_rand_yield); > > > > static CDS_LIST_HEAD(registry); > > > > +/* > > + * Queue keeping threads awaiting to wait for a grace period. Contains > > + * struct gp_waiters_thread objects. > > + */ > > +static DEFINE_URCU_WAIT_QUEUE(gp_waiters); > > + > > static void mutex_lock(pthread_mutex_t *mutex) > > { > > int ret; > > @@ -306,9 +313,31 @@ void synchronize_rcu(void) > > { > > CDS_LIST_HEAD(cur_snap_readers); > > CDS_LIST_HEAD(qsreaders); > > + DEFINE_URCU_WAIT_NODE(wait, URCU_WAIT_WAITING); > > + struct urcu_waiters waiters; > > + > > + /* > > + * Add ourself to gp_waiters queue of threads awaiting to wait > > + * for a grace period. Proceed to perform the grace period only > > + * if we are the first thread added into the queue. > > + */ > > + if (urcu_wait_add(&gp_waiters, &wait) != 0) { > > Actually, we're missing a memory barrier right here. Here is what I'm > adding right away: > > + /* Order previous memory accesses before grace period. */ > + cmm_smp_mb(); Now that I come to think of it, the barrier is needed before urcu_wait_add() rather than after. It's the action on the wait queue (move operation) that order us before the start of the grace period. So instead of adding this barrier, I'm going to document that there is an implicit memory barrier before urcu_wait_add(), and document this barrier in the urcu_wait_add API. I will also document an implicit memory barrier after urcu_move_waiters, which orders the queue moving memory access prior to the beginning of the grace period. Thanks, Mathieu > > Thanks, > > Mathieu > > > > + /* Not first in queue: will be awakened by another thread. */ > > + urcu_adaptative_busy_wait(&wait); > > + /* Order following memory accesses after grace period. */ > > + cmm_smp_mb(); > > + return; > > + } > > + /* We won't need to wake ourself up */ > > + urcu_wait_set_state(&wait, URCU_WAIT_RUNNING); > > > > mutex_lock(&rcu_gp_lock); > > > > + /* > > + * Move all waiters into our local queue. > > + */ > > + urcu_move_waiters(&waiters, &gp_waiters); > > + > > if (cds_list_empty(®istry)) > > goto out; > > > > @@ -374,6 +403,13 @@ void synchronize_rcu(void) > > smp_mb_master(RCU_MB_GROUP); > > out: > > mutex_unlock(&rcu_gp_lock); > > + > > + /* > > + * Wakeup waiters only after we have completed the grace period > > + * and have ensured the memory barriers at the end of the grace > > + * period have been issued. > > + */ > > + urcu_wake_all_waiters(&waiters); > > } > > > > /* > > > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 26 15:01:46 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 15:01:46 -0500 Subject: [lttng-dev] [PATCH] urcu-mb/signal/membarrier: batch concurrent synchronize_rcu() In-Reply-To: <50B2E8FB.4000906@cn.fujitsu.com> References: <20121126032220.GA19034@Krystal> <50B2E8FB.4000906@cn.fujitsu.com> Message-ID: <20121126200146.GA30509@Krystal> Hi Lai, Here are the raw results you asked for. I only did a single run for each, and did not specify any CPU affinity, so please keep in mind that results can vary due to NUMA access effects. But the trend is clear: when we have 3 or more updaters, batching is quite effective. With 1-2 updaters, the results vary between a small speedup for batching (for 1 updater) to a small slowdown for batching (2 updaters). I don't have good explanation for the 1-updater speedups, except maybe that accessing a mutex cache-line with a xchg() first might speed things up, but this is really just a guess. Thoughts ? * Serialized synchronize_rcu() -- test_urcu (mb) ./test_urcu 4 1 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 222512859 nr_writes 10723654 nr_ops 233236513 ./test_urcu 4 20 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 722096653 nr_writes 5012429 nr_ops 727109082 ./test_urcu 12 12 20 SUMMARY ./test_urcu testdur 20 nr_readers 12 rdur 0 wdur 0 nr_writers 12 wdelay 0 nr_reads 1822868768 nr_writes 2300787 nr_ops 1825169555 ./test_urcu 16 8 20 SUMMARY ./test_urcu testdur 20 nr_readers 16 rdur 0 wdur 0 nr_writers 8 wdelay 0 nr_reads 2355908375 nr_writes 1604850 nr_ops 2357513225 ./test_urcu 20 4 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 4 wdelay 0 nr_reads 3003457459 nr_writes 1074828 nr_ops 3004532287 ./test_urcu 20 3 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 3 wdelay 0 nr_reads 2956972543 nr_writes 1036556 nr_ops 2958009099 ./test_urcu 20 2 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 2 wdelay 0 nr_reads 2890178860 nr_writes 1030095 nr_ops 2891208955 ./test_urcu 20 1 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 3017482290 nr_writes 783420 nr_ops 3018265710 * Batched synchronize_rcu() -- test_urcu (mb) ./test_urcu 4 1 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 271476751 nr_writes 12858885 nr_ops 284335636 ./test_urcu 4 20 20 SUMMARY ./test_urcu testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 608488583 nr_writes 10080610 nr_ops 618569193 ./test_urcu 12 12 20 SUMMARY ./test_urcu testdur 20 nr_readers 12 rdur 0 wdur 0 nr_writers 12 wdelay 0 nr_reads 1260044362 nr_writes 7957711 nr_ops 1268002073 ./test_urcu 16 8 20 SUMMARY ./test_urcu testdur 20 nr_readers 16 rdur 0 wdur 0 nr_writers 8 wdelay 0 nr_reads 2048890674 nr_writes 5440985 nr_ops 2054331659 ./test_urcu 20 4 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 4 wdelay 0 nr_reads 2819267217 nr_writes 3093008 nr_ops 2822360225 ./test_urcu 20 3 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 3 wdelay 0 nr_reads 3067795320 nr_writes 2817760 nr_ops 3070613080 ./test_urcu 20 2 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 2 wdelay 0 nr_reads 3116770603 nr_writes 2404242 nr_ops 3119174845 ./test_urcu 20 1 20 SUMMARY ./test_urcu testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 2238534130 nr_writes 3737588 nr_ops 2242271718 * Serialized synchronize_rcu() -- test_urcu_signal ./test_urcu_signal 4 1 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 16063309841 nr_writes 9217 nr_ops 16063319058 ./test_urcu_signal 4 20 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 16065183739 nr_writes 9182 nr_ops 16065192921 ./test_urcu_signal 12 12 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 12 rdur 0 wdur 0 nr_writers 12 wdelay 0 nr_reads 48028512672 nr_writes 8890 nr_ops 48028521562 ./test_urcu_signal 16 8 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 16 rdur 0 wdur 0 nr_writers 8 wdelay 0 nr_reads 64001589198 nr_writes 8756 nr_ops 64001597954 ./test_urcu_signal 20 4 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 4 wdelay 0 nr_reads 79907434070 nr_writes 9068 nr_ops 79907443138 ./test_urcu_signal 20 3 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 3 wdelay 0 nr_reads 79987250839 nr_writes 8589 nr_ops 79987259428 ./test_urcu_signal 20 2 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 2 wdelay 0 nr_reads 79749947176 nr_writes 8596 nr_ops 79749955772 ./test_urcu_signal 20 1 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 79751023090 nr_writes 8624 nr_ops 79751031714 * Batched synchronize_rcu() -- test_urcu_signal ./test_urcu_signal 4 1 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 15739087241 nr_writes 9218 nr_ops 15739096459 ./test_urcu_signal 4 20 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 15662135806 nr_writes 94833 nr_ops 15662230639 ./test_urcu_signal 12 12 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 12 rdur 0 wdur 0 nr_writers 12 wdelay 0 nr_reads 46634363289 nr_writes 56903 nr_ops 46634420192 ./test_urcu_signal 16 8 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 16 rdur 0 wdur 0 nr_writers 8 wdelay 0 nr_reads 62263951759 nr_writes 39058 nr_ops 62263990817 ./test_urcu_signal 20 4 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 4 wdelay 0 nr_reads 77799768623 nr_writes 21065 nr_ops 77799789688 ./test_urcu_signal 20 3 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 3 wdelay 0 nr_reads 76408008440 nr_writes 17026 nr_ops 76408025466 ./test_urcu_signal 20 2 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 2 wdelay 0 nr_reads 77868927424 nr_writes 12630 nr_ops 77868940054 ./test_urcu_signal 20 1 20 SUMMARY ./test_urcu_signal testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 77293186844 nr_writes 8680 nr_ops 77293195524 * Serialized synchronize_rcu() -- test_urcu_qsbr ./test_urcu_qsbr 4 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 18841016559 nr_writes 1857130 nr_ops 18842873689 ./test_urcu_qsbr 4 20 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 20272811733 nr_writes 1837027 nr_ops 20274648760 ./test_urcu_qsbr 12 12 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 12 rdur 0 wdur 0 nr_writers 12 wdelay 0 nr_reads 60343516643 nr_writes 2353685 nr_ops 60345870328 ./test_urcu_qsbr 16 8 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 16 rdur 0 wdur 0 nr_writers 8 wdelay 0 nr_reads 78202711840 nr_writes 2326331 nr_ops 78205038171 ./test_urcu_qsbr 20 4 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 4 wdelay 0 nr_reads 94553396003 nr_writes 2238396 nr_ops 94555634399 ./test_urcu_qsbr 20 3 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 3 wdelay 0 nr_reads 95004708661 nr_writes 2165966 nr_ops 95006874627 ./test_urcu_qsbr 20 2 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 2 wdelay 0 nr_reads 95386506198 nr_writes 2194352 nr_ops 95388700550 ./test_urcu_qsbr 20 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 84705972017 nr_writes 2609595 nr_ops 84708581612 * Batched synchronize_rcu() -- test_urcu_qsbr ./test_urcu_qsbr 4 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 19154850714 nr_writes 2238834 nr_ops 19157089548 ./test_urcu_qsbr 4 20 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 4 rdur 0 wdur 0 nr_writers 20 wdelay 0 nr_reads 15114131760 nr_writes 9370255 nr_ops 15123502015 ./test_urcu_qsbr 12 12 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 12 rdur 0 wdur 0 nr_writers 12 wdelay 0 nr_reads 45541854970 nr_writes 5786496 nr_ops 45547641466 ./test_urcu_qsbr 16 8 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 16 rdur 0 wdur 0 nr_writers 8 wdelay 0 nr_reads 66217337547 nr_writes 4257427 nr_ops 66221594974 ./test_urcu_qsbr 20 4 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 4 wdelay 0 nr_reads 95048642908 nr_writes 2416266 nr_ops 95051059174 ./test_urcu_qsbr 20 3 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 3 wdelay 0 nr_reads 96679609928 nr_writes 2211168 nr_ops 96681821096 ./test_urcu_qsbr 20 2 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 2 wdelay 0 nr_reads 92166219811 nr_writes 1968725 nr_ops 92168188536 ./test_urcu_qsbr 20 1 20 SUMMARY ./test_urcu_qsbr testdur 20 nr_readers 20 rdur 0 wdur 0 nr_writers 1 wdelay 0 nr_reads 87986181951 nr_writes 3278737 nr_ops 87989460688 -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 26 15:16:59 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 15:16:59 -0500 Subject: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust-tracepoint-event.h needs -Wsystem-headers In-Reply-To: <20998D40D9A2B7499CA5A3A2666CB1EB19F87B5C@ZURMSG1.QUANTUM.com> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> <20121119162618.GA17428@Krystal> <20998D40D9A2B7499CA5A3A2666CB1EB19F87B5C@ZURMSG1.QUANTUM.com> Message-ID: <20121126201659.GB30509@Krystal> * David OShea (David.OShea at quantum.com) wrote: > Hi Mathieu, > > Thanks for the response and apologies for the delay in mine, please see below: > > > -----Original Message----- > > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > > Sent: Tuesday, 20 November 2012 2:56 AM > > To: David OShea > > Cc: lttng-dev at lists.lttng.org > > Subject: Re: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust- > > tracepoint-event.h needs -Wsystem-headers > [...] > > > I'm not sure if there is any way you could "fix" this so that > > > -Wsystem-headers isn't required, but perhaps it would at least be > > > worth documenting that this flag could be used - but perhaps not > > > recommend it - to enable those checks to occur. > > > > I have not found any way to show those warnings from UST system headers > > without -Wsystem-headers. We have the following scenario: > > > > probe C file > > -> includes ust probe description file > > -> includes tracepoint-event.h (system header) > > -> includes ust probe description file > > -> includes ust-tracepoint-event.h (system header) [1] > > For each stage: > > -> undef/define macros > > -> includes ust probe description file > > > > Since the actual functions are created by the compiler in the scope of > > ust-tracepoint-event.h [1] (a system header), the warnings are > > inhibited > > unless we specify -Wsystem-headers. > [...] > > So I guess documenting this would be the right way to do it, unless > > anyone has a better idea ? > > I don't know much about the macros in ust-tracepoint-event.h, so this > might not make any sense, but could you have the > __tracepoint_provider_check_##TRACEPOINT_PROVIDER() function actually > get called from the __lttng_events_init__##TRACEPOINT_PROVIDER() > (constructor) function? I assume this would mean you'd get link-time > errors if you have a provider name mismatch. It would also mean a lot > of useless calls to empty functions at startup, but I assume that > really shouldn't take too long. Perhaps this checking could be a > compile-time option, so that if you're concerned about the startup > time impact you can disable it, or perhaps the functions could be > marked as inline? That makes sense! Can you try the following patch and let me know if it fixes your problem? Thanks, Mathieu commit f26441658685b281756ccbc8f74d70b9f2e6dad5 Author: Mathieu Desnoyers Date: Mon Nov 26 15:14:24 2012 -0500 Print probe provider mismatch error even without -Wsystem-headers Suggested-by: David OShea Signed-off-by: Mathieu Desnoyers diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index 8f804d6..c341e04 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -72,7 +72,7 @@ void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(vo #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ __tracepoint_provider_mismatch_##_provider(); -static __attribute__((unused)) +static inline void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void) { #include TRACEPOINT_INCLUDE @@ -655,6 +655,15 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) { int ret; + /* + * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a + * static inline function that ensures every probe PROVIDER + * argument match the provider within which they appear. It + * calls empty static inline functions, and therefore has no + * runtime effect. However, if it detects an error, a linker + * error will appear. + */ + _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(); ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); assert(!ret); } -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 26 15:28:36 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 15:28:36 -0500 Subject: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust-tracepoint-event.h needs -Wsystem-headers In-Reply-To: <20121126201659.GB30509@Krystal> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> <20121119162618.GA17428@Krystal> <20998D40D9A2B7499CA5A3A2666CB1EB19F87B5C@ZURMSG1.QUANTUM.com> <20121126201659.GB30509@Krystal> Message-ID: <20121126202836.GA30838@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * David OShea (David.OShea at quantum.com) wrote: > > Hi Mathieu, > > > > Thanks for the response and apologies for the delay in mine, please see below: > > > > > -----Original Message----- > > > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > > > Sent: Tuesday, 20 November 2012 2:56 AM > > > To: David OShea > > > Cc: lttng-dev at lists.lttng.org > > > Subject: Re: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust- > > > tracepoint-event.h needs -Wsystem-headers > > [...] > > > > I'm not sure if there is any way you could "fix" this so that > > > > -Wsystem-headers isn't required, but perhaps it would at least be > > > > worth documenting that this flag could be used - but perhaps not > > > > recommend it - to enable those checks to occur. > > > > > > I have not found any way to show those warnings from UST system headers > > > without -Wsystem-headers. We have the following scenario: > > > > > > probe C file > > > -> includes ust probe description file > > > -> includes tracepoint-event.h (system header) > > > -> includes ust probe description file > > > -> includes ust-tracepoint-event.h (system header) [1] > > > For each stage: > > > -> undef/define macros > > > -> includes ust probe description file > > > > > > Since the actual functions are created by the compiler in the scope of > > > ust-tracepoint-event.h [1] (a system header), the warnings are > > > inhibited > > > unless we specify -Wsystem-headers. > > [...] > > > So I guess documenting this would be the right way to do it, unless > > > anyone has a better idea ? > > > > I don't know much about the macros in ust-tracepoint-event.h, so this > > might not make any sense, but could you have the > > __tracepoint_provider_check_##TRACEPOINT_PROVIDER() function actually > > get called from the __lttng_events_init__##TRACEPOINT_PROVIDER() > > (constructor) function? I assume this would mean you'd get link-time > > errors if you have a provider name mismatch. It would also mean a lot > > of useless calls to empty functions at startup, but I assume that > > really shouldn't take too long. Perhaps this checking could be a > > compile-time option, so that if you're concerned about the startup > > time impact you can disable it, or perhaps the functions could be > > marked as inline? > > That makes sense! > > Can you try the following patch and let me know if it fixes your > problem? hrm, actually, even without the patch, I get: sample.o:(__tracepoints+0x18): undefined reference to `__tracepoint_provider_sadfasdmple_component' if I try to compile a tracepoint with an incorrect provider name. So the patch would not be needed. I'm using gcc 4.7.2 (Debian 4.7.2-4). Maybe the fact that you don't get any linker error is because of specific behavior wrt unused attribute of your gcc 4.3.3 ? Thanks, Mathieu > > Thanks, > > Mathieu > > commit f26441658685b281756ccbc8f74d70b9f2e6dad5 > Author: Mathieu Desnoyers > Date: Mon Nov 26 15:14:24 2012 -0500 > > Print probe provider mismatch error even without -Wsystem-headers > > Suggested-by: David OShea > Signed-off-by: Mathieu Desnoyers > > diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h > index 8f804d6..c341e04 100644 > --- a/include/lttng/ust-tracepoint-event.h > +++ b/include/lttng/ust-tracepoint-event.h > @@ -72,7 +72,7 @@ void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(vo > #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ > __tracepoint_provider_mismatch_##_provider(); > > -static __attribute__((unused)) > +static inline > void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void) > { > #include TRACEPOINT_INCLUDE > @@ -655,6 +655,15 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) > { > int ret; > > + /* > + * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a > + * static inline function that ensures every probe PROVIDER > + * argument match the provider within which they appear. It > + * calls empty static inline functions, and therefore has no > + * runtime effect. However, if it detects an error, a linker > + * error will appear. > + */ > + _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(); > ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); > assert(!ret); > } > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 26 15:35:58 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 15:35:58 -0500 Subject: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust-tracepoint-event.h needs -Wsystem-headers In-Reply-To: <20121126202836.GA30838@Krystal> References: <20998D40D9A2B7499CA5A3A2666CB1EB19F87106@ZURMSG1.QUANTUM.com> <20121119162618.GA17428@Krystal> <20998D40D9A2B7499CA5A3A2666CB1EB19F87B5C@ZURMSG1.QUANTUM.com> <20121126201659.GB30509@Krystal> <20121126202836.GA30838@Krystal> Message-ID: <20121126203558.GA31535@Krystal> * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > * Mathieu Desnoyers (mathieu.desnoyers at efficios.com) wrote: > > * David OShea (David.OShea at quantum.com) wrote: > > > Hi Mathieu, > > > > > > Thanks for the response and apologies for the delay in mine, please see below: > > > > > > > -----Original Message----- > > > > From: Mathieu Desnoyers [mailto:mathieu.desnoyers at efficios.com] > > > > Sent: Tuesday, 20 November 2012 2:56 AM > > > > To: David OShea > > > > Cc: lttng-dev at lists.lttng.org > > > > Subject: Re: [lttng-dev] TRACEPOINT_PROVIDER mismatch check in ust- > > > > tracepoint-event.h needs -Wsystem-headers > > > [...] > > > > > I'm not sure if there is any way you could "fix" this so that > > > > > -Wsystem-headers isn't required, but perhaps it would at least be > > > > > worth documenting that this flag could be used - but perhaps not > > > > > recommend it - to enable those checks to occur. > > > > > > > > I have not found any way to show those warnings from UST system headers > > > > without -Wsystem-headers. We have the following scenario: > > > > > > > > probe C file > > > > -> includes ust probe description file > > > > -> includes tracepoint-event.h (system header) > > > > -> includes ust probe description file > > > > -> includes ust-tracepoint-event.h (system header) [1] > > > > For each stage: > > > > -> undef/define macros > > > > -> includes ust probe description file > > > > > > > > Since the actual functions are created by the compiler in the scope of > > > > ust-tracepoint-event.h [1] (a system header), the warnings are > > > > inhibited > > > > unless we specify -Wsystem-headers. > > > [...] > > > > So I guess documenting this would be the right way to do it, unless > > > > anyone has a better idea ? > > > > > > I don't know much about the macros in ust-tracepoint-event.h, so this > > > might not make any sense, but could you have the > > > __tracepoint_provider_check_##TRACEPOINT_PROVIDER() function actually > > > get called from the __lttng_events_init__##TRACEPOINT_PROVIDER() > > > (constructor) function? I assume this would mean you'd get link-time > > > errors if you have a provider name mismatch. It would also mean a lot > > > of useless calls to empty functions at startup, but I assume that > > > really shouldn't take too long. Perhaps this checking could be a > > > compile-time option, so that if you're concerned about the startup > > > time impact you can disable it, or perhaps the functions could be > > > marked as inline? > > > > That makes sense! > > > > Can you try the following patch and let me know if it fixes your > > problem? > > hrm, actually, even without the patch, I get: > > sample.o:(__tracepoints+0x18): undefined reference to `__tracepoint_provider_sadfasdmple_component' > > if I try to compile a tracepoint with an incorrect provider name. So the > patch would not be needed. I'm using gcc 4.7.2 (Debian 4.7.2-4). > > Maybe the fact that you don't get any linker error is because of > specific behavior wrt unused attribute of your gcc 4.3.3 ? Ah, but indeed, the linking error, only in the application, is not very verbose. If I install the patch into my system, I get: sample.o:(__tracepoints+0x18): undefined reference to `__tracepoint_provider_sadfasdmple_component' tp.o: In function `__lttng_events_init__sample_component': tp.c:(.text.startup+0x7): undefined reference to `__tracepoint_provider_mismatch_sadfasdmple_component' tp.c:(.text.startup+0xe): undefined reference to `__tracepoint_provider_mismatch_sadfasdmple_component' collect2: ld returned 1 exit status So yes, I think I'll pull this patch into master and stable-2.0. Thanks! Mathieu > > Thanks, > > Mathieu > > > > > Thanks, > > > > Mathieu > > > > commit f26441658685b281756ccbc8f74d70b9f2e6dad5 > > Author: Mathieu Desnoyers > > Date: Mon Nov 26 15:14:24 2012 -0500 > > > > Print probe provider mismatch error even without -Wsystem-headers > > > > Suggested-by: David OShea > > Signed-off-by: Mathieu Desnoyers > > > > diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h > > index 8f804d6..c341e04 100644 > > --- a/include/lttng/ust-tracepoint-event.h > > +++ b/include/lttng/ust-tracepoint-event.h > > @@ -72,7 +72,7 @@ void _TP_COMBINE_TOKENS(__tracepoint_provider_mismatch_, TRACEPOINT_PROVIDER)(vo > > #define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ > > __tracepoint_provider_mismatch_##_provider(); > > > > -static __attribute__((unused)) > > +static inline > > void _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(void) > > { > > #include TRACEPOINT_INCLUDE > > @@ -655,6 +655,15 @@ _TP_COMBINE_TOKENS(__lttng_events_init__, TRACEPOINT_PROVIDER)(void) > > { > > int ret; > > > > + /* > > + * __tracepoint_provider_check_ ## TRACEPOINT_PROVIDER() is a > > + * static inline function that ensures every probe PROVIDER > > + * argument match the provider within which they appear. It > > + * calls empty static inline functions, and therefore has no > > + * runtime effect. However, if it detects an error, a linker > > + * error will appear. > > + */ > > + _TP_COMBINE_TOKENS(__tracepoint_provider_check_, TRACEPOINT_PROVIDER)(); > > ret = lttng_probe_register(&_TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PROVIDER)); > > assert(!ret); > > } > > -- > > Mathieu Desnoyers > > Operating System Efficiency R&D Consultant > > EfficiOS Inc. > > http://www.efficios.com > > > > _______________________________________________ > > lttng-dev mailing list > > lttng-dev at lists.lttng.org > > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev > > -- > Mathieu Desnoyers > Operating System Efficiency R&D Consultant > EfficiOS Inc. > http://www.efficios.com > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 26 15:47:50 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 15:47:50 -0500 Subject: [lttng-dev] [RELEASE] LTTng-UST 2.0.6 Message-ID: <20121126204749.GA31733@Krystal> LTTng-UST, the Linux Trace Toolkit Next Generation Userspace Tracer, is port of the low-overhead tracing capabilities of the LTTng kernel tracer to user-space. The library "liblttng-ust" enables tracing of applications and libraries. Changelog: 2012-11-26 lttng-ust 2.0.6 * Print probe provider mismatch error even without -Wsystem-headers * Fix: Conditionally disable tests requiring shared libs support * Cleanup: don't spawn per-user thread if HOME is not set * Fix: Fix self-assign warning on struct ustfork_clone_info init * Fix: memcpy of string is larger than source * liblttng-ust-fork: override daemon() call * Build out of src tree * Fix: manpage typo "-lllttng-ust" -> "-llttng-ust" * Manpage update: document use in daemons * Fix: get_wait_shm() ust mutex deadlock (add 2 missing exit calls) * Fix: get_wait_shm() ust mutex deadlock Project website: http://lttng.org Download link: http://lttng.org/download (please refer to the README file for installation instructions) -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Mon Nov 26 15:58:08 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Mon, 26 Nov 2012 15:58:08 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Clarify empty string/NULL filter errors Message-ID: <20121126205808.GA32010@Krystal> Reported-by: Jesus Garcia Signed-off-by: Mathieu Desnoyers --- diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h index c6fc605..515e07c 100644 --- a/include/lttng/lttng.h +++ b/include/lttng/lttng.h @@ -516,6 +516,8 @@ extern int lttng_enable_event(struct lttng_handle *handle, * If event_name is NULL, all events are enabled with that filter. * If channel_name is NULL, the default channel is used (channel0) and created * if not found. + * If filter_expression is NULL, an event without associated filter is + * created. */ extern int lttng_enable_event_with_filter(struct lttng_handle *handle, struct lttng_event *event, const char *channel_name, diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c index df47606..d5cfc0e 100644 --- a/src/bin/lttng-sessiond/main.c +++ b/src/bin/lttng-sessiond/main.c @@ -2853,6 +2853,10 @@ skip_domain: ret = LTTNG_ERR_FILTER_INVAL; goto error; } + if (cmd_ctx->lsm->u.enable.bytecode_len == 0) { + ret = LTTNG_ERR_FILTER_INVAL; + goto error; + } bytecode = zmalloc(cmd_ctx->lsm->u.enable.bytecode_len); if (!bytecode) { ret = LTTNG_ERR_FILTER_NOMEM; diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 6238d9a..96351bd 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -841,8 +841,20 @@ int lttng_enable_event_with_filter(struct lttng_handle *handle, FILE *fmem; int ret = 0; - /* Safety check. */ - if (handle == NULL || !filter_expression) { + if (!filter_expression) { + /* + * Fall back to normal event enabling if no filter + * specified. + */ + return lttng_enable_event(handle, event, channel_name); + } + + /* + * Empty filter string will always be rejected by the parser + * anyway, so treat this corner-case early to eliminate + * lttng_fmemopen error for 0-byte allocation. + */ + if (handle == NULL || filter_expression[0] == '\0') { return -LTTNG_ERR_INVALID; } -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From david.bryant at quantum.com Mon Nov 26 23:09:42 2012 From: david.bryant at quantum.com (David Bryant) Date: Tue, 27 Nov 2012 14:39:42 +1030 Subject: [lttng-dev] Test if tracepoint is enabled Message-ID: <50B43D06.7020709@quantum.com> Hi all, Is it feasible to have an officially supported way of determining if a tracepoint is currently enabled? In my code I would like to test if the tracepoint is enabled, and if it isn't, avoid doing expensive setup work. I've been doing the following: if (__builtin_expect(!!(__tracepoint_sample_component___message.state), 0)) { /* setup work */ tracepoint(sample_component, message); /* cleanup work */ } But it's weak for two reasons: * The 'state' attribute goes true when the tracepoint is enabled, but stays true after the tracepoint is disabled. It only goes false when the session is destroyed. * It uses a private / unofficial API What I'd like is an official API that correctly evaluates whether a tracepoint is enabled or not? Is this possible? Thanks, Dave ---------------------------------------------------------------------- The information contained in this transmission may be confidential. Any disclosure, copying, or further distribution of confidential information is not permitted unless such privilege is explicitly granted in writing by Quantum. Quantum reserves the right to have electronic communications, including email and attachments, sent across its networks filtered through anti virus and spam software programs and retain such messages in order to comply with applicable data security and retention requirements. Quantum is not responsible for the proper and complete transmission of the substance of this communication or for any delay in its receipt. -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew_gabbasov at mentor.com Tue Nov 27 07:21:53 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Tue, 27 Nov 2012 06:21:53 -0600 Subject: [lttng-dev] [PATCH lttng-modules] Make upper bound of kernel version checking macro exclusive Message-ID: <1354018913-14211-1-git-send-email-andrew_gabbasov@mentor.com> It's more usable to have the upper limit exclusive. It helps to avoid hardcoding of stable branch highest version number, i.e. having a range from 3.1.0 up to 3.2.0 (exclusively) gives us all 3.1.x versions. Signed-off-by: Andrew Gabbasov --- lttng-kernel-version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lttng-kernel-version.h b/lttng-kernel-version.h index 280a398..0eb56b3 100644 --- a/lttng-kernel-version.h +++ b/lttng-kernel-version.h @@ -27,10 +27,10 @@ /* * This macro checks if the kernel version is between the two specified - * versions (inclusive). + * versions (lower limit inclusive, upper limit exclusive). */ #define LTTNG_KERNEL_RANGE(a_low, b_low, c_low, a_high, b_high, c_high) \ (LINUX_VERSION_CODE >= KERNEL_VERSION(a_low, b_low, c_low) && \ - LINUX_VERSION_CODE <= KERNEL_VERSION(a_high, b_high, c_high)) + LINUX_VERSION_CODE < KERNEL_VERSION(a_high, b_high, c_high)) #endif /* _LTTNG_KERNEL_VERSION_H */ -- 1.7.10.4 From andrew_gabbasov at mentor.com Tue Nov 27 07:22:26 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Tue, 27 Nov 2012 06:22:26 -0600 Subject: [lttng-dev] [PATCH lttng-modules] Update using of kernel version checking macro to new range Message-ID: <1354018946-14252-1-git-send-email-andrew_gabbasov@mentor.com> Signed-off-by: Andrew Gabbasov --- probes/lttng-probe-vmscan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c index 0205c7e..4f5739c 100644 --- a/probes/lttng-probe-vmscan.c +++ b/probes/lttng-probe-vmscan.c @@ -39,8 +39,8 @@ #define CREATE_TRACE_POINTS #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ - LTTNG_KERNEL_RANGE(3,1,0, 3,1,10) +#if ((LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ + LTTNG_KERNEL_RANGE(3,1,0, 3,2,0)) typedef int isolate_mode_t; #endif -- 1.7.10.4 From mathieu.desnoyers at efficios.com Tue Nov 27 11:45:33 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 27 Nov 2012 11:45:33 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Make upper bound of kernel version checking macro exclusive In-Reply-To: <1354018913-14211-1-git-send-email-andrew_gabbasov@mentor.com> References: <1354018913-14211-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121127164533.GA27001@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > It's more usable to have the upper limit exclusive. It helps to avoid > hardcoding of stable branch highest version number, i.e. having a range > from 3.1.0 up to 3.2.0 (exclusively) gives us all 3.1.x versions. > Merged, thanks! Mathieu > Signed-off-by: Andrew Gabbasov > --- > lttng-kernel-version.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/lttng-kernel-version.h b/lttng-kernel-version.h > index 280a398..0eb56b3 100644 > --- a/lttng-kernel-version.h > +++ b/lttng-kernel-version.h > @@ -27,10 +27,10 @@ > > /* > * This macro checks if the kernel version is between the two specified > - * versions (inclusive). > + * versions (lower limit inclusive, upper limit exclusive). > */ > #define LTTNG_KERNEL_RANGE(a_low, b_low, c_low, a_high, b_high, c_high) \ > (LINUX_VERSION_CODE >= KERNEL_VERSION(a_low, b_low, c_low) && \ > - LINUX_VERSION_CODE <= KERNEL_VERSION(a_high, b_high, c_high)) > + LINUX_VERSION_CODE < KERNEL_VERSION(a_high, b_high, c_high)) > > #endif /* _LTTNG_KERNEL_VERSION_H */ > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Tue Nov 27 11:45:45 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Tue, 27 Nov 2012 11:45:45 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Update using of kernel version checking macro to new range In-Reply-To: <1354018946-14252-1-git-send-email-andrew_gabbasov@mentor.com> References: <1354018946-14252-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121127164545.GB27001@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > Signed-off-by: Andrew Gabbasov Merged, thanks! Mathieu > --- > probes/lttng-probe-vmscan.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c > index 0205c7e..4f5739c 100644 > --- a/probes/lttng-probe-vmscan.c > +++ b/probes/lttng-probe-vmscan.c > @@ -39,8 +39,8 @@ > #define CREATE_TRACE_POINTS > #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > > -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ > - LTTNG_KERNEL_RANGE(3,1,0, 3,1,10) > +#if ((LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ > + LTTNG_KERNEL_RANGE(3,1,0, 3,2,0)) > typedef int isolate_mode_t; > #endif > > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From andrew_gabbasov at mentor.com Wed Nov 28 04:55:26 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Wed, 28 Nov 2012 03:55:26 -0600 Subject: [lttng-dev] [PATCH lttng-modules] Update kernel probes to more detailed match to kernel versions Message-ID: <1354096526-22098-1-git-send-email-andrew_gabbasov@mentor.com> We have added some more ifdef's to kernel probes to more closely match the kernel tracepoints for different kernel versions. The changes cover kernel versions from 2.6.38 up to 3.7. We did not track the earlier versions, and they are filtered out in probes Makefile. ext3 probe was modified to use #include <../fs/ext3/ext3.h> instead of copying this include from kernel source to lttng-modules source. Using such includes (there will be more similar in other probes) imposes a restriction to use the full kernel source for building lttng-modules rather than having just kernel "include" directory, but it looks like full source is required anyway, at least with respect to Makefiles structure. May be it is worth mentioning somewhere in the documentation. The code was verified to compile with latest versions in all stable branches from 2.6.38.x to 3.6.x and 3.7-rc7. Thanks. Best regards, Andrew Gabbasov The actual patch is below. >From 81b2f45837cba1e258a79fad6b8b33474d968198 Mon Sep 17 00:00:00 2001 From: Andrew Gabbasov Date: Sat, 24 Nov 2012 14:50:09 -0600 Subject: [PATCH lttng-modules] Update kernel probes to more detailed match to kernel versions Some ifdef's are added to kernel probes instrumentation to make them more close to original tracepoints in different kernel versions. Signed-off-by: Andrew Gabbasov --- instrumentation/events/lttng-module/asoc.h | 82 ++ instrumentation/events/lttng-module/block.h | 25 + instrumentation/events/lttng-module/ext3.h | 6 + instrumentation/events/lttng-module/jbd.h | 22 + instrumentation/events/lttng-module/jbd2.h | 36 + instrumentation/events/lttng-module/kmem.h | 17 +- instrumentation/events/lttng-module/power.h | 42 +- instrumentation/events/lttng-module/sched.h | 37 + instrumentation/events/lttng-module/scsi.h | 37 + instrumentation/events/lttng-module/signal.h | 2 + instrumentation/events/lttng-module/vmscan.h | 138 ++- instrumentation/events/mainline/asoc.h | 80 ++ instrumentation/events/mainline/block.h | 20 +- instrumentation/events/mainline/ext3.h | 4 +- instrumentation/events/mainline/fs_ext3.h | 1323 -------------------------- instrumentation/events/mainline/jbd.h | 39 +- instrumentation/events/mainline/jbd2.h | 29 +- instrumentation/events/mainline/kmem.h | 8 +- instrumentation/events/mainline/power.h | 37 +- instrumentation/events/mainline/sched.h | 17 +- instrumentation/events/mainline/signal.h | 85 +- instrumentation/events/mainline/vmscan.h | 136 +-- probes/Makefile | 16 +- probes/lttng-probe-asoc.c | 2 +- probes/lttng-probe-ext3.c | 8 +- probes/lttng-probe-jbd.c | 1 - probes/lttng-probe-vmscan.c | 6 - 27 files changed, 665 insertions(+), 1590 deletions(-) delete mode 100644 instrumentation/events/mainline/fs_ext3.h diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h index 6ffc923..672bea4 100644 --- a/instrumentation/events/lttng-module/asoc.h +++ b/instrumentation/events/lttng-module/asoc.h @@ -8,6 +8,8 @@ #include #include +#define DAPM_DIRECT "(direct)" + #ifndef _TRACE_ASOC_DEF #define _TRACE_ASOC_DEF struct snd_soc_jack; @@ -251,6 +253,86 @@ TRACE_EVENT(snd_soc_dapm_walk_done, ) #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +TRACE_EVENT(snd_soc_dapm_output_path, + + TP_PROTO(struct snd_soc_dapm_widget *widget, + struct snd_soc_dapm_path *path), + + TP_ARGS(widget, path), + + TP_STRUCT__entry( + __string( wname, widget->name ) + __string( pname, path->name ? path->name : DAPM_DIRECT) + __string( psname, path->sink->name ) + __field( int, path_sink ) + __field( int, path_connect ) + ), + + TP_fast_assign( + tp_strcpy(wname, widget->name) + tp_strcpy(pname, path->name ? path->name : DAPM_DIRECT) + tp_strcpy(psname, path->sink->name) + tp_assign(path_connect, path->connect) + tp_assign(path_sink, (long)path->sink) + ), + + TP_printk("%c%s -> %s -> %s\n", + (int) __entry->path_sink && + (int) __entry->path_connect ? '*' : ' ', + __get_str(wname), __get_str(pname), __get_str(psname)) +) + +TRACE_EVENT(snd_soc_dapm_input_path, + + TP_PROTO(struct snd_soc_dapm_widget *widget, + struct snd_soc_dapm_path *path), + + TP_ARGS(widget, path), + + TP_STRUCT__entry( + __string( wname, widget->name ) + __string( pname, path->name ? path->name : DAPM_DIRECT) + __string( psname, path->source->name ) + __field( int, path_source ) + __field( int, path_connect ) + ), + + TP_fast_assign( + tp_strcpy(wname, widget->name) + tp_strcpy(pname, path->name ? path->name : DAPM_DIRECT) + tp_strcpy(psname, path->source->name) + tp_assign(path_connect, path->connect) + tp_assign(path_source, (long)path->source) + ), + + TP_printk("%c%s <- %s <- %s\n", + (int) __entry->path_source && + (int) __entry->path_connect ? '*' : ' ', + __get_str(wname), __get_str(pname), __get_str(psname)) +) + +TRACE_EVENT(snd_soc_dapm_connected, + + TP_PROTO(int paths, int stream), + + TP_ARGS(paths, stream), + + TP_STRUCT__entry( + __field( int, paths ) + __field( int, stream ) + ), + + TP_fast_assign( + tp_assign(paths, paths) + tp_assign(stream, stream) + ), + + TP_printk("%s: found %d paths\n", + __entry->stream ? "capture" : "playback", __entry->paths) +) +#endif + TRACE_EVENT(snd_soc_jack_irq, TP_PROTO(const char *name), diff --git a/instrumentation/events/lttng-module/block.h b/instrumentation/events/lttng-module/block.h index 42184f3..af34544 100644 --- a/instrumentation/events/lttng-module/block.h +++ b/instrumentation/events/lttng-module/block.h @@ -8,6 +8,9 @@ #include #include #include +#include + +#define RWBS_LEN 8 #ifndef _TRACE_BLOCK_DEF_ #define _TRACE_BLOCK_DEF_ @@ -22,20 +25,40 @@ enum { RWBS_FLAG_SYNC = (1 << 4), RWBS_FLAG_META = (1 << 5), RWBS_FLAG_SECURE = (1 << 6), + RWBS_FLAG_FLUSH = (1 << 7), + RWBS_FLAG_FUA = (1 << 8), }; #endif /* _TRACE_BLOCK_DEF_ */ #define __print_rwbs_flags(rwbs) \ __print_flags(rwbs, "", \ + { RWBS_FLAG_FLUSH, "F" }, \ { RWBS_FLAG_WRITE, "W" }, \ { RWBS_FLAG_DISCARD, "D" }, \ { RWBS_FLAG_READ, "R" }, \ + { RWBS_FLAG_FUA, "F" }, \ { RWBS_FLAG_RAHEAD, "A" }, \ { RWBS_FLAG_SYNC, "S" }, \ { RWBS_FLAG_META, "M" }, \ { RWBS_FLAG_SECURE, "E" }) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) + +#define blk_fill_rwbs(rwbs, rw, bytes) \ + tp_assign(rwbs, ((rw) & WRITE ? RWBS_FLAG_WRITE : \ + ( (rw) & REQ_DISCARD ? RWBS_FLAG_DISCARD : \ + ( (bytes) ? RWBS_FLAG_READ : \ + ( 0 )))) \ + | ((rw) & REQ_RAHEAD ? RWBS_FLAG_RAHEAD : 0) \ + | ((rw) & REQ_SYNC ? RWBS_FLAG_SYNC : 0) \ + | ((rw) & REQ_META ? RWBS_FLAG_META : 0) \ + | ((rw) & REQ_SECURE ? RWBS_FLAG_SECURE : 0) \ + | ((rw) & REQ_FLUSH ? RWBS_FLAG_FLUSH : 0) \ + | ((rw) & REQ_FUA ? RWBS_FLAG_FUA : 0)) + +#else + #define blk_fill_rwbs(rwbs, rw, bytes) \ tp_assign(rwbs, ((rw) & WRITE ? RWBS_FLAG_WRITE : \ ( (rw) & REQ_DISCARD ? RWBS_FLAG_DISCARD : \ @@ -46,6 +69,8 @@ enum { | ((rw) & REQ_META ? RWBS_FLAG_META : 0) \ | ((rw) & REQ_SECURE ? RWBS_FLAG_SECURE : 0)) +#endif + DECLARE_EVENT_CLASS(block_rq_with_error, TP_PROTO(struct request_queue *q, struct request *rq), diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h index f1b4aa9..32917fb 100644 --- a/instrumentation/events/lttng-module/ext3.h +++ b/instrumentation/events/lttng-module/ext3.h @@ -5,6 +5,7 @@ #define _TRACE_EXT3_H #include +#include TRACE_EVENT(ext3_free_inode, TP_PROTO(struct inode *inode), @@ -24,8 +25,13 @@ TRACE_EVENT(ext3_free_inode, tp_assign(dev, inode->i_sb->s_dev) tp_assign(ino, inode->i_ino) tp_assign(mode, inode->i_mode) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) + tp_assign(uid, i_uid_read(inode)) + tp_assign(gid, i_gid_read(inode)) +#else tp_assign(uid, inode->i_uid) tp_assign(gid, inode->i_gid) +#endif tp_assign(blocks, inode->i_blocks) ), diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h index b6bd64a..570bdac 100644 --- a/instrumentation/events/lttng-module/jbd.h +++ b/instrumentation/events/lttng-module/jbd.h @@ -6,6 +6,7 @@ #include #include +#include TRACE_EVENT(jbd_checkpoint, @@ -217,6 +218,26 @@ TRACE_EVENT(jbd_cleanup_journal_tail, __entry->block_nr, __entry->freed) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +TRACE_EVENT(journal_write_superblock, + TP_PROTO(journal_t *journal, int write_op), + + TP_ARGS(journal, write_op), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, write_op ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(write_op, write_op) + ), + + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), + MINOR(__entry->dev), __entry->write_op) +) +#else TRACE_EVENT(jbd_update_superblock_end, TP_PROTO(journal_t *journal, int wait), @@ -236,6 +257,7 @@ TRACE_EVENT(jbd_update_superblock_end, MAJOR(__entry->dev), MINOR(__entry->dev), __entry->wait) ) +#endif #endif /* _TRACE_JBD_H */ diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h index c7992c0..cc6b933 100644 --- a/instrumentation/events/lttng-module/jbd2.h +++ b/instrumentation/events/lttng-module/jbd2.h @@ -6,6 +6,7 @@ #include #include +#include #ifndef _TRACE_JBD2_DEF #define _TRACE_JBD2_DEF @@ -84,6 +85,15 @@ DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, TP_ARGS(journal, commit_transaction) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +DEFINE_EVENT(jbd2_commit, jbd2_drop_transaction, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +) +#endif + TRACE_EVENT(jbd2_end_commit, TP_PROTO(journal_t *journal, transaction_t *commit_transaction), @@ -203,7 +213,11 @@ TRACE_EVENT(jbd2_checkpoint_stats, __entry->forced_to_close, __entry->written, __entry->dropped) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +TRACE_EVENT(jbd2_update_log_tail, +#else TRACE_EVENT(jbd2_cleanup_journal_tail, +#endif TP_PROTO(journal_t *journal, tid_t first_tid, unsigned long block_nr, unsigned long freed), @@ -232,6 +246,28 @@ TRACE_EVENT(jbd2_cleanup_journal_tail, __entry->block_nr, __entry->freed) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +TRACE_EVENT(jbd2_write_superblock, + + TP_PROTO(journal_t *journal, int write_op), + + TP_ARGS(journal, write_op), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, write_op ) + ), + + TP_fast_assign( + tp_assign(dev, journal->j_fs_dev->bd_dev) + tp_assign(write_op, write_op) + ), + + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), + MINOR(__entry->dev), __entry->write_op) +) +#endif + #endif /* _TRACE_JBD2_H */ /* This part must be outside protection */ diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h index dab8989..11938d1 100644 --- a/instrumentation/events/lttng-module/kmem.h +++ b/instrumentation/events/lttng-module/kmem.h @@ -4,6 +4,11 @@ #if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KMEM_H +#include +#include +#include +#include + DECLARE_EVENT_CLASS(kmem_alloc, TP_PROTO(unsigned long call_site, @@ -143,7 +148,11 @@ DEFINE_EVENT(kmem_free, kmem_cache_free, TP_ARGS(call_site, ptr) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +TRACE_EVENT(mm_page_free, +#else TRACE_EVENT(mm_page_free_direct, +#endif TP_PROTO(struct page *page, unsigned int order), @@ -165,7 +174,11 @@ TRACE_EVENT(mm_page_free_direct, __entry->order) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +TRACE_EVENT(mm_page_free_batched, +#else TRACE_EVENT(mm_pagevec_free, +#endif TP_PROTO(struct page *page, int cold), @@ -210,7 +223,7 @@ TRACE_EVENT(mm_page_alloc, TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", __entry->page, - page_to_pfn(__entry->page), + __entry->page ? page_to_pfn(__entry->page) : 0, __entry->order, __entry->migratetype, show_gfp_flags(__entry->gfp_flags)) @@ -236,7 +249,7 @@ DECLARE_EVENT_CLASS(mm_page, TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", __entry->page, - page_to_pfn(__entry->page), + __entry->page ? page_to_pfn(__entry->page) : 0, __entry->order, __entry->migratetype, __entry->order == 0) diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h index f2e3f54..6023593 100644 --- a/instrumentation/events/lttng-module/power.h +++ b/instrumentation/events/lttng-module/power.h @@ -6,6 +6,7 @@ #include #include +#include DECLARE_EVENT_CLASS(cpu, @@ -65,7 +66,42 @@ TRACE_EVENT(machine_suspend, TP_printk("state=%lu", (unsigned long)__entry->state) ) -/* This code will be removed after deprecation time exceeded (2.6.41) */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) +DECLARE_EVENT_CLASS(wakeup_source, + + TP_PROTO(const char *name, unsigned int state), + + TP_ARGS(name, state), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + ), + + TP_fast_assign( + tp_strcpy(name, name) + tp_assign(state, state) + ), + + TP_printk("%s state=0x%lx", __get_str(name), + (unsigned long)__entry->state) +) + +DEFINE_EVENT(wakeup_source, wakeup_source_activate, + + TP_PROTO(const char *name, unsigned int state), + + TP_ARGS(name, state) +) + +DEFINE_EVENT(wakeup_source, wakeup_source_deactivate, + + TP_PROTO(const char *name, unsigned int state), + + TP_ARGS(name, state) +) +#endif + #ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED /* @@ -151,6 +187,10 @@ enum { events get removed */ static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; static inline void trace_power_end(u64 cpuid) {}; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) +static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {}; +static inline void trace_power_end_rcuidle(u64 cpuid) {}; +#endif static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; #endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ diff --git a/instrumentation/events/lttng-module/sched.h b/instrumentation/events/lttng-module/sched.h index 005f3d1..b84aef7 100644 --- a/instrumentation/events/lttng-module/sched.h +++ b/instrumentation/events/lttng-module/sched.h @@ -6,6 +6,8 @@ #include #include +#include +#include #ifndef _TRACE_SCHED_DEF_ #define _TRACE_SCHED_DEF_ @@ -19,8 +21,12 @@ static inline long __trace_sched_switch_state(struct task_struct *p) * For all intents and purposes a preempted task is a running task. */ if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + state = TASK_RUNNING | TASK_STATE_MAX; +#else state = TASK_RUNNING; #endif +#endif return state; } @@ -98,6 +104,11 @@ DECLARE_EVENT_CLASS(sched_wakeup_template, tp_assign(prio, p->prio) tp_assign(success, success) tp_assign(target_cpu, task_cpu(p)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + ) + TP_perf_assign( + __perf_task(p) +#endif ), TP_printk("comm=%s tid=%d prio=%d success=%d target_cpu=%03d", @@ -170,6 +181,17 @@ TRACE_EVENT(sched_switch, tp_assign(next_prio, next->prio - MAX_RT_PRIO) ), +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) + TP_printk("prev_comm=%s prev_tid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_tid=%d next_prio=%d", + __entry->prev_comm, __entry->prev_tid, __entry->prev_prio, + __entry->prev_state & (TASK_STATE_MAX-1) ? + __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|", + { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, + { 16, "Z" }, { 32, "X" }, { 64, "x" }, + { 128, "W" }) : "R", + __entry->prev_state & TASK_STATE_MAX ? "+" : "", + __entry->next_comm, __entry->next_tid, __entry->next_prio) +#else TP_printk("prev_comm=%s prev_tid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_tid=%d next_prio=%d", __entry->prev_comm, __entry->prev_tid, __entry->prev_prio, __entry->prev_state ? @@ -178,6 +200,7 @@ TRACE_EVENT(sched_switch, { 16, "Z" }, { 32, "X" }, { 64, "x" }, { 128, "W" }) : "R", __entry->next_comm, __entry->next_tid, __entry->next_prio) +#endif ) /* @@ -396,6 +419,15 @@ DEFINE_EVENT(sched_stat_template, sched_stat_iowait, TP_PROTO(struct task_struct *tsk, u64 delay), TP_ARGS(tsk, delay)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) +/* + * Tracepoint for accounting blocked time (time the task is in uninterruptible). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_blocked, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)) +#endif + /* * Tracepoint for accounting runtime (time the task is executing * on a CPU). @@ -421,6 +453,9 @@ TRACE_EVENT(sched_stat_runtime, ) TP_perf_assign( __perf_count(runtime) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) + __perf_task(tsk) +#endif ), TP_printk("comm=%s tid=%d runtime=%Lu [ns] vruntime=%Lu [ns]", @@ -429,6 +464,7 @@ TRACE_EVENT(sched_stat_runtime, (unsigned long long)__entry->vruntime) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) /* * Tracepoint for showing priority inheritance modifying a tasks * priority. @@ -457,6 +493,7 @@ TRACE_EVENT(sched_pi_setprio, __entry->comm, __entry->tid, __entry->oldprio, __entry->newprio) ) +#endif #endif /* _TRACE_SCHED_H */ diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h index 18d2b02..15f0c70 100644 --- a/instrumentation/events/lttng-module/scsi.h +++ b/instrumentation/events/lttng-module/scsi.h @@ -8,6 +8,7 @@ #include #include #include +#include #ifndef _TRACE_SCSI_DEF #define _TRACE_SCSI_DEF @@ -187,6 +188,7 @@ scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) #define scsi_prot_op_name(result) { result, #result } #define show_prot_op_name(val) \ __print_symbolic(val, \ @@ -197,6 +199,7 @@ scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ scsi_prot_op_name(SCSI_PROT_READ_PASS), \ scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) +#endif const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); #define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) @@ -217,7 +220,9 @@ TRACE_EVENT(scsi_dispatch_cmd_start, __field( unsigned int, cmd_len ) __field( unsigned int, data_sglen ) __field( unsigned int, prot_sglen ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) __field( unsigned char, prot_op ) +#endif __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) ), @@ -230,15 +235,24 @@ TRACE_EVENT(scsi_dispatch_cmd_start, tp_assign(cmd_len, cmd->cmd_len) tp_assign(data_sglen, scsi_sg_count(cmd)) tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) tp_assign(prot_op, scsi_get_prot_op(cmd)) +#endif tp_memcpy_dyn(cmnd, cmd->cmnd) ), +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ " prot_op=%s cmnd=(%s %s raw=%s)", +#else + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " cmnd=(%s %s raw=%s)", +#endif __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) show_prot_op_name(__entry->prot_op), +#endif show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) @@ -260,7 +274,9 @@ TRACE_EVENT(scsi_dispatch_cmd_error, __field( unsigned int, cmd_len ) __field( unsigned int, data_sglen ) __field( unsigned int, prot_sglen ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) __field( unsigned char, prot_op ) +#endif __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) ), @@ -274,15 +290,24 @@ TRACE_EVENT(scsi_dispatch_cmd_error, tp_assign(cmd_len, cmd->cmd_len) tp_assign(data_sglen, scsi_sg_count(cmd)) tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) tp_assign(prot_op, scsi_get_prot_op(cmd)) +#endif tp_memcpy_dyn(cmnd, cmd->cmnd) ), +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", +#else + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ + " cmnd=(%s %s raw=%s) rtn=%d", +#endif __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) show_prot_op_name(__entry->prot_op), +#endif show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), @@ -305,7 +330,9 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, __field( unsigned int, cmd_len ) __field( unsigned int, data_sglen ) __field( unsigned int, prot_sglen ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) __field( unsigned char, prot_op ) +#endif __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) ), @@ -319,16 +346,26 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, tp_assign(cmd_len, cmd->cmd_len) tp_assign(data_sglen, scsi_sg_count(cmd)) tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) tp_assign(prot_op, scsi_get_prot_op(cmd)) +#endif tp_memcpy_dyn(cmnd, cmd->cmnd) ), +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ "%s host=%s message=%s status=%s)", +#else + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ + "prot_sgl=%u cmnd=(%s %s raw=%s) result=(driver=%s host=%s " \ + "message=%s status=%s)", +#endif __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) show_prot_op_name(__entry->prot_op), +#endif show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), diff --git a/instrumentation/events/lttng-module/signal.h b/instrumentation/events/lttng-module/signal.h index 945747f..a1c904b 100644 --- a/instrumentation/events/lttng-module/signal.h +++ b/instrumentation/events/lttng-module/signal.h @@ -135,6 +135,7 @@ TRACE_EVENT(signal_deliver, __entry->sa_handler, __entry->sa_flags) ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) DECLARE_EVENT_CLASS(signal_queue_overflow, TP_PROTO(int sig, int group, struct siginfo *info), @@ -193,6 +194,7 @@ DEFINE_EVENT(signal_queue_overflow, signal_lose_info, TP_ARGS(sig, group, info) ) +#endif #endif /* _TRACE_SIGNAL_H */ diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h index d6ab952..3bb8696 100644 --- a/instrumentation/events/lttng-module/vmscan.h +++ b/instrumentation/events/lttng-module/vmscan.h @@ -4,6 +4,65 @@ #if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_VMSCAN_H +#include +#include +#include +#include +#include +#include + +#ifndef _TRACE_VMSCAN_DEF +#define _TRACE_VMSCAN_DEF +#define RECLAIM_WB_ANON 0x0001u +#define RECLAIM_WB_FILE 0x0002u +#define RECLAIM_WB_MIXED 0x0010u +#define RECLAIM_WB_SYNC 0x0004u /* Unused, all reclaim async */ +#define RECLAIM_WB_ASYNC 0x0008u + +#define show_reclaim_flags(flags) \ + (flags) ? __print_flags(flags, "|", \ + {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ + {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ + {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ + {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ + {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ + ) : "RECLAIM_WB_NONE" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + +#define trace_reclaim_flags(page, sync) ( \ + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + ) + +#define trace_shrink_flags(file, sync) ( \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + ) + +#else + +#define trace_reclaim_flags(page) ( \ + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ + (RECLAIM_WB_ASYNC) \ + ) + +#define trace_shrink_flags(file) \ + ( \ + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ + (RECLAIM_WB_ASYNC) \ + ) + +#endif + +#if ((LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ + LTTNG_KERNEL_RANGE(3,1,0, 3,2,0)) +typedef int isolate_mode_t; +#endif + +#endif + TRACE_EVENT(mm_vmscan_kswapd_sleep, TP_PROTO(int nid), @@ -147,6 +206,7 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_re TP_ARGS(nr_reclaimed) ) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) TRACE_EVENT(mm_shrink_slab_start, TP_PROTO(struct shrinker *shr, struct shrink_control *sc, long nr_objects_to_shrink, unsigned long pgs_scanned, @@ -224,6 +284,7 @@ TRACE_EVENT(mm_shrink_slab_end, __entry->total_scan, __entry->retval) ) +#endif DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, @@ -231,30 +292,41 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, unsigned long nr_requested, unsigned long nr_scanned, unsigned long nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) unsigned long nr_lumpy_taken, unsigned long nr_lumpy_dirty, unsigned long nr_lumpy_failed, +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) - isolate_mode_t isolate_mode), + isolate_mode_t isolate_mode #else isolate_mode_t isolate_mode, - int file), + int file #endif + ), + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), + isolate_mode #else - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file), + isolate_mode, file #endif + ), + TP_STRUCT__entry( __field(int, order) __field(unsigned long, nr_requested) __field(unsigned long, nr_scanned) __field(unsigned long, nr_taken) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) __field(unsigned long, nr_lumpy_taken) __field(unsigned long, nr_lumpy_dirty) __field(unsigned long, nr_lumpy_failed) +#endif __field(isolate_mode_t, isolate_mode) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) __field(int, file) @@ -266,9 +338,11 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, tp_assign(nr_requested, nr_requested) tp_assign(nr_scanned, nr_scanned) tp_assign(nr_taken, nr_taken) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) tp_assign(nr_lumpy_taken, nr_lumpy_taken) tp_assign(nr_lumpy_dirty, nr_lumpy_dirty) tp_assign(nr_lumpy_failed, nr_lumpy_failed) +#endif tp_assign(isolate_mode, isolate_mode) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) tp_assign(file, file) @@ -277,9 +351,6 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", -#else - TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", -#endif __entry->isolate_mode, __entry->order, __entry->nr_requested, @@ -287,11 +358,26 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, __entry->nr_taken, __entry->nr_lumpy_taken, __entry->nr_lumpy_dirty, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) __entry->nr_lumpy_failed) -#else +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", + __entry->isolate_mode, + __entry->order, + __entry->nr_requested, + __entry->nr_scanned, + __entry->nr_taken, + __entry->nr_lumpy_taken, + __entry->nr_lumpy_dirty, __entry->nr_lumpy_failed, __entry->file) +#else + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d", + __entry->isolate_mode, + __entry->order, + __entry->nr_requested, + __entry->nr_scanned, + __entry->nr_taken, + __entry->file) #endif ) @@ -307,19 +393,23 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, unsigned long nr_lumpy_failed, #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) - isolate_mode_t isolate_mode), + isolate_mode_t isolate_mode #else isolate_mode_t isolate_mode, - int file), + int file #endif + ), + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) + isolate_mode #else - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) + isolate_mode, file #endif + ) ) @@ -335,19 +425,23 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, unsigned long nr_lumpy_failed, #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) - isolate_mode_t isolate_mode), + isolate_mode_t isolate_mode #else isolate_mode_t isolate_mode, - int file), + int file #endif + ), + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) + nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) + isolate_mode #else - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) + isolate_mode, file #endif + ) ) @@ -408,7 +502,6 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, ) #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) - TRACE_EVENT(replace_swap_token, TP_PROTO(struct mm_struct *old_mm, struct mm_struct *new_mm), @@ -490,7 +583,6 @@ TRACE_EVENT_CONDITION(update_swap_token_priority, __entry->mm, __entry->old_prio, __entry->new_prio, __entry->swap_token_mm, __entry->swap_token_prio) ) - #endif #endif /* _TRACE_VMSCAN_H */ diff --git a/instrumentation/events/mainline/asoc.h b/instrumentation/events/mainline/asoc.h index ab26f8a..5fc2dcd 100644 --- a/instrumentation/events/mainline/asoc.h +++ b/instrumentation/events/mainline/asoc.h @@ -7,6 +7,8 @@ #include #include +#define DAPM_DIRECT "(direct)" + struct snd_soc_jack; struct snd_soc_codec; struct snd_soc_platform; @@ -241,6 +243,84 @@ TRACE_EVENT(snd_soc_dapm_walk_done, (int)__entry->path_checks, (int)__entry->neighbour_checks) ); +TRACE_EVENT(snd_soc_dapm_output_path, + + TP_PROTO(struct snd_soc_dapm_widget *widget, + struct snd_soc_dapm_path *path), + + TP_ARGS(widget, path), + + TP_STRUCT__entry( + __string( wname, widget->name ) + __string( pname, path->name ? path->name : DAPM_DIRECT) + __string( psname, path->sink->name ) + __field( int, path_sink ) + __field( int, path_connect ) + ), + + TP_fast_assign( + __assign_str(wname, widget->name); + __assign_str(pname, path->name ? path->name : DAPM_DIRECT); + __assign_str(psname, path->sink->name); + __entry->path_connect = path->connect; + __entry->path_sink = (long)path->sink; + ), + + TP_printk("%c%s -> %s -> %s\n", + (int) __entry->path_sink && + (int) __entry->path_connect ? '*' : ' ', + __get_str(wname), __get_str(pname), __get_str(psname)) +); + +TRACE_EVENT(snd_soc_dapm_input_path, + + TP_PROTO(struct snd_soc_dapm_widget *widget, + struct snd_soc_dapm_path *path), + + TP_ARGS(widget, path), + + TP_STRUCT__entry( + __string( wname, widget->name ) + __string( pname, path->name ? path->name : DAPM_DIRECT) + __string( psname, path->source->name ) + __field( int, path_source ) + __field( int, path_connect ) + ), + + TP_fast_assign( + __assign_str(wname, widget->name); + __assign_str(pname, path->name ? path->name : DAPM_DIRECT); + __assign_str(psname, path->source->name); + __entry->path_connect = path->connect; + __entry->path_source = (long)path->source; + ), + + TP_printk("%c%s <- %s <- %s\n", + (int) __entry->path_source && + (int) __entry->path_connect ? '*' : ' ', + __get_str(wname), __get_str(pname), __get_str(psname)) +); + +TRACE_EVENT(snd_soc_dapm_connected, + + TP_PROTO(int paths, int stream), + + TP_ARGS(paths, stream), + + TP_STRUCT__entry( + __field( int, paths ) + __field( int, stream ) + ), + + TP_fast_assign( + __entry->paths = paths; + __entry->stream = stream; + ), + + TP_printk("%s: found %d paths\n", + __entry->stream ? "capture" : "playback", __entry->paths) +); + TRACE_EVENT(snd_soc_jack_irq, TP_PROTO(const char *name), diff --git a/instrumentation/events/mainline/block.h b/instrumentation/events/mainline/block.h index bf36654..05c5e61 100644 --- a/instrumentation/events/mainline/block.h +++ b/instrumentation/events/mainline/block.h @@ -8,6 +8,8 @@ #include #include +#define RWBS_LEN 8 + DECLARE_EVENT_CLASS(block_rq_with_error, TP_PROTO(struct request_queue *q, struct request *rq), @@ -19,7 +21,7 @@ DECLARE_EVENT_CLASS(block_rq_with_error, __field( sector_t, sector ) __field( unsigned int, nr_sector ) __field( int, errors ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN ) __dynamic_array( char, cmd, blk_cmd_buf_len(rq) ) ), @@ -104,7 +106,7 @@ DECLARE_EVENT_CLASS(block_rq, __field( sector_t, sector ) __field( unsigned int, nr_sector ) __field( unsigned int, bytes ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN ) __array( char, comm, TASK_COMM_LEN ) __dynamic_array( char, cmd, blk_cmd_buf_len(rq) ) ), @@ -183,7 +185,7 @@ TRACE_EVENT(block_bio_bounce, __field( dev_t, dev ) __field( sector_t, sector ) __field( unsigned int, nr_sector ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN ) __array( char, comm, TASK_COMM_LEN ) ), @@ -222,7 +224,7 @@ TRACE_EVENT(block_bio_complete, __field( sector_t, sector ) __field( unsigned, nr_sector ) __field( int, error ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN) ), TP_fast_assign( @@ -249,7 +251,7 @@ DECLARE_EVENT_CLASS(block_bio, __field( dev_t, dev ) __field( sector_t, sector ) __field( unsigned int, nr_sector ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN ) __array( char, comm, TASK_COMM_LEN ) ), @@ -321,7 +323,7 @@ DECLARE_EVENT_CLASS(block_get_rq, __field( dev_t, dev ) __field( sector_t, sector ) __field( unsigned int, nr_sector ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN ) __array( char, comm, TASK_COMM_LEN ) ), @@ -456,7 +458,7 @@ TRACE_EVENT(block_split, __field( dev_t, dev ) __field( sector_t, sector ) __field( sector_t, new_sector ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN ) __array( char, comm, TASK_COMM_LEN ) ), @@ -498,7 +500,7 @@ TRACE_EVENT(block_bio_remap, __field( unsigned int, nr_sector ) __field( dev_t, old_dev ) __field( sector_t, old_sector ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN) ), TP_fast_assign( @@ -542,7 +544,7 @@ TRACE_EVENT(block_rq_remap, __field( unsigned int, nr_sector ) __field( dev_t, old_dev ) __field( sector_t, old_sector ) - __array( char, rwbs, 6 ) + __array( char, rwbs, RWBS_LEN) ), TP_fast_assign( diff --git a/instrumentation/events/mainline/ext3.h b/instrumentation/events/mainline/ext3.h index 7b53c05..15d11a3 100644 --- a/instrumentation/events/mainline/ext3.h +++ b/instrumentation/events/mainline/ext3.h @@ -24,8 +24,8 @@ TRACE_EVENT(ext3_free_inode, __entry->dev = inode->i_sb->s_dev; __entry->ino = inode->i_ino; __entry->mode = inode->i_mode; - __entry->uid = inode->i_uid; - __entry->gid = inode->i_gid; + __entry->uid = i_uid_read(inode); + __entry->gid = i_gid_read(inode); __entry->blocks = inode->i_blocks; ), diff --git a/instrumentation/events/mainline/fs_ext3.h b/instrumentation/events/mainline/fs_ext3.h deleted file mode 100644 index 76353e4..0000000 --- a/instrumentation/events/mainline/fs_ext3.h +++ /dev/null @@ -1,1323 +0,0 @@ -/* - * Written by Stephen C. Tweedie , 1999 - * - * Copyright 1998--1999 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. - * - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card at masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include -#include -#include -#include -#include - -/* - * The second extended filesystem constants/structures - */ - -/* - * Define EXT3FS_DEBUG to produce debug messages - */ -#undef EXT3FS_DEBUG - -/* - * Define EXT3_RESERVATION to reserve data blocks for expanding files - */ -#define EXT3_DEFAULT_RESERVE_BLOCKS 8 -/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ -#define EXT3_MAX_RESERVE_BLOCKS 1027 -#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 - -/* - * Debug code - */ -#ifdef EXT3FS_DEBUG -#define ext3_debug(f, a...) \ - do { \ - printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __func__); \ - printk (KERN_DEBUG f, ## a); \ - } while (0) -#else -#define ext3_debug(f, a...) do {} while (0) -#endif - -/* - * Special inodes numbers - */ -#define EXT3_BAD_INO 1 /* Bad blocks inode */ -#define EXT3_ROOT_INO 2 /* Root inode */ -#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ -#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ -#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ -#define EXT3_JOURNAL_INO 8 /* Journal inode */ - -/* First non-reserved inode for old ext3 filesystems */ -#define EXT3_GOOD_OLD_FIRST_INO 11 - -/* - * Maximal count of links to a file - */ -#define EXT3_LINK_MAX 32000 - -/* - * Macro-instructions used to manage several block sizes - */ -#define EXT3_MIN_BLOCK_SIZE 1024 -#define EXT3_MAX_BLOCK_SIZE 65536 -#define EXT3_MIN_BLOCK_LOG_SIZE 10 -#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) -#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) -#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) -#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) -#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) - -/* - * Macro-instructions used to manage fragments - */ -#define EXT3_MIN_FRAG_SIZE 1024 -#define EXT3_MAX_FRAG_SIZE 4096 -#define EXT3_MIN_FRAG_LOG_SIZE 10 -#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) -#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) - -/* - * Structure of a blocks group descriptor - */ -struct ext3_group_desc -{ - __le32 bg_block_bitmap; /* Blocks bitmap block */ - __le32 bg_inode_bitmap; /* Inodes bitmap block */ - __le32 bg_inode_table; /* Inodes table block */ - __le16 bg_free_blocks_count; /* Free blocks count */ - __le16 bg_free_inodes_count; /* Free inodes count */ - __le16 bg_used_dirs_count; /* Directories count */ - __u16 bg_pad; - __le32 bg_reserved[3]; -}; - -/* - * Macro-instructions used to manage group descriptors - */ -#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) -#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) -#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) -#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) - -/* - * Constants relative to the data blocks - */ -#define EXT3_NDIR_BLOCKS 12 -#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS -#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1) -#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1) -#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1) - -/* - * Inode flags - */ -#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */ -#define EXT3_UNRM_FL 0x00000002 /* Undelete */ -#define EXT3_COMPR_FL 0x00000004 /* Compress file */ -#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */ -#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */ -#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */ -#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */ -#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */ -/* Reserved for compression usage... */ -#define EXT3_DIRTY_FL 0x00000100 -#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ -#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */ -#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */ -/* End compression flags --- maybe not all used */ -#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */ -#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ -#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ -#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ -#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ -#define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ -#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ - -#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ -#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ - -/* Flags that should be inherited by new inodes from their parent. */ -#define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ - EXT3_SYNC_FL | EXT3_NODUMP_FL |\ - EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\ - EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\ - EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL) - -/* Flags that are appropriate for regular files (all but dir-specific ones). */ -#define EXT3_REG_FLMASK (~(EXT3_DIRSYNC_FL | EXT3_TOPDIR_FL)) - -/* Flags that are appropriate for non-directories/regular files. */ -#define EXT3_OTHER_FLMASK (EXT3_NODUMP_FL | EXT3_NOATIME_FL) - -/* Mask out flags that are inappropriate for the given type of inode. */ -static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) -{ - if (S_ISDIR(mode)) - return flags; - else if (S_ISREG(mode)) - return flags & EXT3_REG_FLMASK; - else - return flags & EXT3_OTHER_FLMASK; -} - -/* Used to pass group descriptor data when online resize is done */ -struct ext3_new_group_input { - __u32 group; /* Group number for this data */ - __u32 block_bitmap; /* Absolute block number of block bitmap */ - __u32 inode_bitmap; /* Absolute block number of inode bitmap */ - __u32 inode_table; /* Absolute block number of inode table start */ - __u32 blocks_count; /* Total number of blocks in this group */ - __u16 reserved_blocks; /* Number of reserved blocks in this group */ - __u16 unused; -}; - -/* The struct ext3_new_group_input in kernel space, with free_blocks_count */ -struct ext3_new_group_data { - __u32 group; - __u32 block_bitmap; - __u32 inode_bitmap; - __u32 inode_table; - __u32 blocks_count; - __u16 reserved_blocks; - __u16 unused; - __u32 free_blocks_count; -}; - - -/* - * ioctl commands - */ -#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS -#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS -#define EXT3_IOC_GETVERSION _IOR('f', 3, long) -#define EXT3_IOC_SETVERSION _IOW('f', 4, long) -#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) -#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input) -#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION -#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION -#ifdef CONFIG_JBD_DEBUG -#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) -#endif -#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) -#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long) - -/* - * ioctl commands in 32 bit emulation - */ -#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS -#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) -#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) -#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) -#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) -#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) -#ifdef CONFIG_JBD_DEBUG -#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) -#endif -#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION -#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION - - -/* - * Mount options - */ -struct ext3_mount_options { - unsigned long s_mount_opt; - uid_t s_resuid; - gid_t s_resgid; - unsigned long s_commit_interval; -#ifdef CONFIG_QUOTA - int s_jquota_fmt; - char *s_qf_names[MAXQUOTAS]; -#endif -}; - -/* - * Structure of an inode on the disk - */ -struct ext3_inode { - __le16 i_mode; /* File mode */ - __le16 i_uid; /* Low 16 bits of Owner Uid */ - __le32 i_size; /* Size in bytes */ - __le32 i_atime; /* Access time */ - __le32 i_ctime; /* Creation time */ - __le32 i_mtime; /* Modification time */ - __le32 i_dtime; /* Deletion Time */ - __le16 i_gid; /* Low 16 bits of Group Id */ - __le16 i_links_count; /* Links count */ - __le32 i_blocks; /* Blocks count */ - __le32 i_flags; /* File flags */ - union { - struct { - __u32 l_i_reserved1; - } linux1; - struct { - __u32 h_i_translator; - } hurd1; - struct { - __u32 m_i_reserved1; - } masix1; - } osd1; /* OS dependent 1 */ - __le32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */ - __le32 i_generation; /* File version (for NFS) */ - __le32 i_file_acl; /* File ACL */ - __le32 i_dir_acl; /* Directory ACL */ - __le32 i_faddr; /* Fragment address */ - union { - struct { - __u8 l_i_frag; /* Fragment number */ - __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; - __le16 l_i_uid_high; /* these 2 fields */ - __le16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; - } linux2; - struct { - __u8 h_i_frag; /* Fragment number */ - __u8 h_i_fsize; /* Fragment size */ - __u16 h_i_mode_high; - __u16 h_i_uid_high; - __u16 h_i_gid_high; - __u32 h_i_author; - } hurd2; - struct { - __u8 m_i_frag; /* Fragment number */ - __u8 m_i_fsize; /* Fragment size */ - __u16 m_pad1; - __u32 m_i_reserved2[2]; - } masix2; - } osd2; /* OS dependent 2 */ - __le16 i_extra_isize; - __le16 i_pad1; -}; - -#define i_size_high i_dir_acl - -#define i_reserved1 osd1.linux1.l_i_reserved1 -#define i_frag osd2.linux2.l_i_frag -#define i_fsize osd2.linux2.l_i_fsize -#define i_uid_low i_uid -#define i_gid_low i_gid -#define i_uid_high osd2.linux2.l_i_uid_high -#define i_gid_high osd2.linux2.l_i_gid_high -#define i_reserved2 osd2.linux2.l_i_reserved2 - -/* - * File system states - */ -#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */ -#define EXT3_ERROR_FS 0x0002 /* Errors detected */ -#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */ - -/* - * Misc. filesystem flags - */ -#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ -#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ -#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ - -/* - * Mount flags - */ -#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */ -/* EXT3_MOUNT_OLDALLOC was there */ -#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */ -#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */ -#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ -#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ -#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ -#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ -#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ -#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */ -#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ -#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ -#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ -#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ -#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ -#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ -#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ -#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ -#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ -#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ -#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ -#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ -#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write - * error in ordered mode */ - -/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ -#ifndef _LINUX_EXT2_FS_H -#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt -#define set_opt(o, opt) o |= EXT3_MOUNT_##opt -#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ - EXT3_MOUNT_##opt) -#else -#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD -#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT -#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS -#endif - -#define ext3_set_bit __set_bit_le -#define ext3_set_bit_atomic ext2_set_bit_atomic -#define ext3_clear_bit __clear_bit_le -#define ext3_clear_bit_atomic ext2_clear_bit_atomic -#define ext3_test_bit test_bit_le -#define ext3_find_next_zero_bit find_next_zero_bit_le - -/* - * Maximal mount counts between two filesystem checks - */ -#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ -#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */ - -/* - * Behaviour when detecting errors - */ -#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */ -#define EXT3_ERRORS_RO 2 /* Remount fs read-only */ -#define EXT3_ERRORS_PANIC 3 /* Panic */ -#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE - -/* - * Structure of the super block - */ -struct ext3_super_block { -/*00*/ __le32 s_inodes_count; /* Inodes count */ - __le32 s_blocks_count; /* Blocks count */ - __le32 s_r_blocks_count; /* Reserved blocks count */ - __le32 s_free_blocks_count; /* Free blocks count */ -/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ - __le32 s_first_data_block; /* First Data Block */ - __le32 s_log_block_size; /* Block size */ - __le32 s_log_frag_size; /* Fragment size */ -/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ - __le32 s_frags_per_group; /* # Fragments per group */ - __le32 s_inodes_per_group; /* # Inodes per group */ - __le32 s_mtime; /* Mount time */ -/*30*/ __le32 s_wtime; /* Write time */ - __le16 s_mnt_count; /* Mount count */ - __le16 s_max_mnt_count; /* Maximal mount count */ - __le16 s_magic; /* Magic signature */ - __le16 s_state; /* File system state */ - __le16 s_errors; /* Behaviour when detecting errors */ - __le16 s_minor_rev_level; /* minor revision level */ -/*40*/ __le32 s_lastcheck; /* time of last check */ - __le32 s_checkinterval; /* max. time between checks */ - __le32 s_creator_os; /* OS */ - __le32 s_rev_level; /* Revision level */ -/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ - __le16 s_def_resgid; /* Default gid for reserved blocks */ - /* - * These fields are for EXT3_DYNAMIC_REV superblocks only. - * - * Note: the difference between the compatible feature set and - * the incompatible feature set is that if there is a bit set - * in the incompatible feature set that the kernel doesn't - * know about, it should refuse to mount the filesystem. - * - * e2fsck's requirements are more strict; if it doesn't know - * about a feature in either the compatible or incompatible - * feature set, it must abort and not try to meddle with - * things it doesn't understand... - */ - __le32 s_first_ino; /* First non-reserved inode */ - __le16 s_inode_size; /* size of inode structure */ - __le16 s_block_group_nr; /* block group # of this superblock */ - __le32 s_feature_compat; /* compatible feature set */ -/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ - __le32 s_feature_ro_compat; /* readonly-compatible feature set */ -/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ -/*78*/ char s_volume_name[16]; /* volume name */ -/*88*/ char s_last_mounted[64]; /* directory where last mounted */ -/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ - /* - * Performance hints. Directory preallocation should only - * happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on. - */ - __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ - __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ - __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ - /* - * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. - */ -/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ -/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ - __le32 s_journal_dev; /* device number of journal file */ - __le32 s_last_orphan; /* start of list of inodes to delete */ - __le32 s_hash_seed[4]; /* HTREE hash seed */ - __u8 s_def_hash_version; /* Default hash version to use */ - __u8 s_reserved_char_pad; - __u16 s_reserved_word_pad; - __le32 s_default_mount_opts; - __le32 s_first_meta_bg; /* First metablock block group */ - __le32 s_mkfs_time; /* When the filesystem was created */ - __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ - /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ -/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ - __le32 s_r_blocks_count_hi; /* Reserved blocks count */ - __le32 s_free_blocks_count_hi; /* Free blocks count */ - __le16 s_min_extra_isize; /* All inodes have at least # bytes */ - __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ - __le32 s_flags; /* Miscellaneous flags */ - __le16 s_raid_stride; /* RAID stride */ - __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ - __le64 s_mmp_block; /* Block for multi-mount protection */ - __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ - __u8 s_log_groups_per_flex; /* FLEX_BG group size */ - __u8 s_reserved_char_pad2; - __le16 s_reserved_pad; - __u32 s_reserved[162]; /* Padding to the end of the block */ -}; - -/* data type for block offset of block group */ -typedef int ext3_grpblk_t; - -/* data type for filesystem-wide blocks number */ -typedef unsigned long ext3_fsblk_t; - -#define E3FSBLK "%lu" - -struct ext3_reserve_window { - ext3_fsblk_t _rsv_start; /* First byte reserved */ - ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ -}; - -struct ext3_reserve_window_node { - struct rb_node rsv_node; - __u32 rsv_goal_size; - __u32 rsv_alloc_hit; - struct ext3_reserve_window rsv_window; -}; - -struct ext3_block_alloc_info { - /* information about reservation window */ - struct ext3_reserve_window_node rsv_window_node; - /* - * was i_next_alloc_block in ext3_inode_info - * is the logical (file-relative) number of the - * most-recently-allocated block in this file. - * We use this for detecting linearly ascending allocation requests. - */ - __u32 last_alloc_logical_block; - /* - * Was i_next_alloc_goal in ext3_inode_info - * is the *physical* companion to i_next_alloc_block. - * it the physical block number of the block which was most-recentl - * allocated to this file. This give us the goal (target) for the next - * allocation when we detect linearly ascending requests. - */ - ext3_fsblk_t last_alloc_physical_block; -}; - -#define rsv_start rsv_window._rsv_start -#define rsv_end rsv_window._rsv_end - -/* - * third extended file system inode data in memory - */ -struct ext3_inode_info { - __le32 i_data[15]; /* unconverted */ - __u32 i_flags; -#ifdef EXT3_FRAGMENTS - __u32 i_faddr; - __u8 i_frag_no; - __u8 i_frag_size; -#endif - ext3_fsblk_t i_file_acl; - __u32 i_dir_acl; - __u32 i_dtime; - - /* - * i_block_group is the number of the block group which contains - * this file's inode. Constant across the lifetime of the inode, - * it is ued for making block allocation decisions - we try to - * place a file's data blocks near its inode block, and new inodes - * near to their parent directory's inode. - */ - __u32 i_block_group; - unsigned long i_state_flags; /* Dynamic state flags for ext3 */ - - /* block reservation info */ - struct ext3_block_alloc_info *i_block_alloc_info; - - __u32 i_dir_start_lookup; -#ifdef CONFIG_EXT3_FS_XATTR - /* - * Extended attributes can be read independently of the main file - * data. Taking i_mutex even when reading would cause contention - * between readers of EAs and writers of regular file data, so - * instead we synchronize on xattr_sem when reading or changing - * EAs. - */ - struct rw_semaphore xattr_sem; -#endif - - struct list_head i_orphan; /* unlinked but open inodes */ - - /* - * i_disksize keeps track of what the inode size is ON DISK, not - * in memory. During truncate, i_size is set to the new size by - * the VFS prior to calling ext3_truncate(), but the filesystem won't - * set i_disksize to 0 until the truncate is actually under way. - * - * The intent is that i_disksize always represents the blocks which - * are used by this file. This allows recovery to restart truncate - * on orphans if we crash during truncate. We actually write i_disksize - * into the on-disk inode when writing inodes out, instead of i_size. - * - * The only time when i_disksize and i_size may be different is when - * a truncate is in progress. The only things which change i_disksize - * are ext3_get_block (growth) and ext3_truncate (shrinkth). - */ - loff_t i_disksize; - - /* on-disk additional length */ - __u16 i_extra_isize; - - /* - * truncate_mutex is for serialising ext3_truncate() against - * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's - * data tree are chopped off during truncate. We can't do that in - * ext3 because whenever we perform intermediate commits during - * truncate, the inode and all the metadata blocks *must* be in a - * consistent state which allows truncation of the orphans to restart - * during recovery. Hence we must fix the get_block-vs-truncate race - * by other means, so we have truncate_mutex. - */ - struct mutex truncate_mutex; - - /* - * Transactions that contain inode's metadata needed to complete - * fsync and fdatasync, respectively. - */ - atomic_t i_sync_tid; - atomic_t i_datasync_tid; - - struct inode vfs_inode; -}; - -/* - * third extended-fs super-block data in memory - */ -struct ext3_sb_info { - unsigned long s_frag_size; /* Size of a fragment in bytes */ - unsigned long s_frags_per_block;/* Number of fragments per block */ - unsigned long s_inodes_per_block;/* Number of inodes per block */ - unsigned long s_frags_per_group;/* Number of fragments in a group */ - unsigned long s_blocks_per_group;/* Number of blocks in a group */ - unsigned long s_inodes_per_group;/* Number of inodes in a group */ - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ - unsigned long s_gdb_count; /* Number of group descriptor blocks */ - unsigned long s_desc_per_block; /* Number of group descriptors per block */ - unsigned long s_groups_count; /* Number of groups in the fs */ - unsigned long s_overhead_last; /* Last calculated overhead */ - unsigned long s_blocks_last; /* Last seen block count */ - struct buffer_head * s_sbh; /* Buffer containing the super block */ - struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ - struct buffer_head ** s_group_desc; - unsigned long s_mount_opt; - ext3_fsblk_t s_sb_block; - uid_t s_resuid; - gid_t s_resgid; - unsigned short s_mount_state; - unsigned short s_pad; - int s_addr_per_block_bits; - int s_desc_per_block_bits; - int s_inode_size; - int s_first_ino; - spinlock_t s_next_gen_lock; - u32 s_next_generation; - u32 s_hash_seed[4]; - int s_def_hash_version; - int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ - struct percpu_counter s_freeblocks_counter; - struct percpu_counter s_freeinodes_counter; - struct percpu_counter s_dirs_counter; - struct blockgroup_lock *s_blockgroup_lock; - - /* root of the per fs reservation window tree */ - spinlock_t s_rsv_window_lock; - struct rb_root s_rsv_window_root; - struct ext3_reserve_window_node s_rsv_window_head; - - /* Journaling */ - struct inode * s_journal_inode; - struct journal_s * s_journal; - struct list_head s_orphan; - struct mutex s_orphan_lock; - struct mutex s_resize_lock; - unsigned long s_commit_interval; - struct block_device *journal_bdev; -#ifdef CONFIG_QUOTA - char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ - int s_jquota_fmt; /* Format of quota to use */ -#endif -}; - -static inline spinlock_t * -sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) -{ - return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); -} - -static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} -static inline struct ext3_inode_info *EXT3_I(struct inode *inode) -{ - return container_of(inode, struct ext3_inode_info, vfs_inode); -} - -static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) -{ - return ino == EXT3_ROOT_INO || - ino == EXT3_JOURNAL_INO || - ino == EXT3_RESIZE_INO || - (ino >= EXT3_FIRST_INO(sb) && - ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); -} - -/* - * Inode dynamic state flags - */ -enum { - EXT3_STATE_JDATA, /* journaled data exists */ - EXT3_STATE_NEW, /* inode is newly created */ - EXT3_STATE_XATTR, /* has in-inode xattrs */ - EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ -}; - -static inline int ext3_test_inode_state(struct inode *inode, int bit) -{ - return test_bit(bit, &EXT3_I(inode)->i_state_flags); -} - -static inline void ext3_set_inode_state(struct inode *inode, int bit) -{ - set_bit(bit, &EXT3_I(inode)->i_state_flags); -} - -static inline void ext3_clear_inode_state(struct inode *inode, int bit) -{ - clear_bit(bit, &EXT3_I(inode)->i_state_flags); -} - -#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime - -/* - * Codes for operating systems - */ -#define EXT3_OS_LINUX 0 -#define EXT3_OS_HURD 1 -#define EXT3_OS_MASIX 2 -#define EXT3_OS_FREEBSD 3 -#define EXT3_OS_LITES 4 - -/* - * Revision levels - */ -#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */ -#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ - -#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV -#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV - -#define EXT3_GOOD_OLD_INODE_SIZE 128 - -/* - * Feature set definitions - */ - -#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \ - ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) -#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \ - ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) -#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \ - ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) -#define EXT3_SET_COMPAT_FEATURE(sb,mask) \ - EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) -#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \ - EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) -#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \ - EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) -#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \ - EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) -#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ - EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) -#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \ - EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) - -#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001 -#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002 -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 -#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008 -#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010 -#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020 - -#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 - -#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001 -#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ -#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 - -#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR -#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER| \ - EXT3_FEATURE_INCOMPAT_META_BG) -#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT3_FEATURE_RO_COMPAT_BTREE_DIR) - -/* - * Default values for user and/or group using reserved blocks - */ -#define EXT3_DEF_RESUID 0 -#define EXT3_DEF_RESGID 0 - -/* - * Default mount options - */ -#define EXT3_DEFM_DEBUG 0x0001 -#define EXT3_DEFM_BSDGROUPS 0x0002 -#define EXT3_DEFM_XATTR_USER 0x0004 -#define EXT3_DEFM_ACL 0x0008 -#define EXT3_DEFM_UID16 0x0010 -#define EXT3_DEFM_JMODE 0x0060 -#define EXT3_DEFM_JMODE_DATA 0x0020 -#define EXT3_DEFM_JMODE_ORDERED 0x0040 -#define EXT3_DEFM_JMODE_WBACK 0x0060 - -/* - * Structure of a directory entry - */ -#define EXT3_NAME_LEN 255 - -struct ext3_dir_entry { - __le32 inode; /* Inode number */ - __le16 rec_len; /* Directory entry length */ - __le16 name_len; /* Name length */ - char name[EXT3_NAME_LEN]; /* File name */ -}; - -/* - * The new version of the directory entry. Since EXT3 structures are - * stored in intel byte order, and the name_len field could never be - * bigger than 255 chars, it's safe to reclaim the extra byte for the - * file_type field. - */ -struct ext3_dir_entry_2 { - __le32 inode; /* Inode number */ - __le16 rec_len; /* Directory entry length */ - __u8 name_len; /* Name length */ - __u8 file_type; - char name[EXT3_NAME_LEN]; /* File name */ -}; - -/* - * Ext3 directory file types. Only the low 3 bits are used. The - * other bits are reserved for now. - */ -#define EXT3_FT_UNKNOWN 0 -#define EXT3_FT_REG_FILE 1 -#define EXT3_FT_DIR 2 -#define EXT3_FT_CHRDEV 3 -#define EXT3_FT_BLKDEV 4 -#define EXT3_FT_FIFO 5 -#define EXT3_FT_SOCK 6 -#define EXT3_FT_SYMLINK 7 - -#define EXT3_FT_MAX 8 - -/* - * EXT3_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 4 - */ -#define EXT3_DIR_PAD 4 -#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) -#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) -#define EXT3_MAX_REC_LEN ((1<<16)-1) - -/* - * Tests against MAX_REC_LEN etc were put in place for 64k block - * sizes; if that is not possible on this arch, we can skip - * those tests and speed things up. - */ -static inline unsigned ext3_rec_len_from_disk(__le16 dlen) -{ - unsigned len = le16_to_cpu(dlen); - -#if (PAGE_CACHE_SIZE >= 65536) - if (len == EXT3_MAX_REC_LEN) - return 1 << 16; -#endif - return len; -} - -static inline __le16 ext3_rec_len_to_disk(unsigned len) -{ -#if (PAGE_CACHE_SIZE >= 65536) - if (len == (1 << 16)) - return cpu_to_le16(EXT3_MAX_REC_LEN); - else if (len > (1 << 16)) - BUG(); -#endif - return cpu_to_le16(len); -} - -/* - * Hash Tree Directory indexing - * (c) Daniel Phillips, 2001 - */ - -#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ - EXT3_FEATURE_COMPAT_DIR_INDEX) && \ - (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) -#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) -#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) - -/* Legal values for the dx_root hash_version field: */ - -#define DX_HASH_LEGACY 0 -#define DX_HASH_HALF_MD4 1 -#define DX_HASH_TEA 2 -#define DX_HASH_LEGACY_UNSIGNED 3 -#define DX_HASH_HALF_MD4_UNSIGNED 4 -#define DX_HASH_TEA_UNSIGNED 5 - -/* hash info structure used by the directory hash */ -struct dx_hash_info -{ - u32 hash; - u32 minor_hash; - int hash_version; - u32 *seed; -}; - -#define EXT3_HTREE_EOF 0x7fffffff - -/* - * Control parameters used by ext3_htree_next_block - */ -#define HASH_NB_ALWAYS 1 - - -/* - * Describe an inode's exact location on disk and in memory - */ -struct ext3_iloc -{ - struct buffer_head *bh; - unsigned long offset; - unsigned long block_group; -}; - -static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc) -{ - return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset); -} - -/* - * This structure is stuffed into the struct file's private_data field - * for directories. It is where we put information so that we can do - * readdir operations in hash tree order. - */ -struct dir_private_info { - struct rb_root root; - struct rb_node *curr_node; - struct fname *extra_fname; - loff_t last_pos; - __u32 curr_hash; - __u32 curr_minor_hash; - __u32 next_hash; -}; - -/* calculate the first block number of the group */ -static inline ext3_fsblk_t -ext3_group_first_block_no(struct super_block *sb, unsigned long group_no) -{ - return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) + - le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); -} - -/* - * Special error return code only used by dx_probe() and its callers. - */ -#define ERR_BAD_DX_DIR -75000 - -/* - * Function prototypes - */ - -/* - * Ok, these declarations are also in but none of the - * ext3 source programs needs to include it so they are duplicated here. - */ -# define NORET_TYPE /**/ -# define ATTRIB_NORET __attribute__((noreturn)) -# define NORET_AND noreturn, - -/* balloc.c */ -extern int ext3_bg_has_super(struct super_block *sb, int group); -extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); -extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode, - ext3_fsblk_t goal, int *errp); -extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode, - ext3_fsblk_t goal, unsigned long *count, int *errp); -extern void ext3_free_blocks (handle_t *handle, struct inode *inode, - ext3_fsblk_t block, unsigned long count); -extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb, - ext3_fsblk_t block, unsigned long count, - unsigned long *pdquot_freed_blocks); -extern ext3_fsblk_t ext3_count_free_blocks (struct super_block *); -extern void ext3_check_blocks_bitmap (struct super_block *); -extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, - unsigned int block_group, - struct buffer_head ** bh); -extern int ext3_should_retry_alloc(struct super_block *sb, int *retries); -extern void ext3_init_block_alloc_info(struct inode *); -extern void ext3_rsv_window_add(struct super_block *sb, struct ext3_reserve_window_node *rsv); -extern int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range); - -/* dir.c */ -extern int ext3_check_dir_entry(const char *, struct inode *, - struct ext3_dir_entry_2 *, - struct buffer_head *, unsigned long); -extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, - __u32 minor_hash, - struct ext3_dir_entry_2 *dirent); -extern void ext3_htree_free_dir_info(struct dir_private_info *p); - -/* fsync.c */ -extern int ext3_sync_file(struct file *, loff_t, loff_t, int); - -/* hash.c */ -extern int ext3fs_dirhash(const char *name, int len, struct - dx_hash_info *hinfo); - -/* ialloc.c */ -extern struct inode * ext3_new_inode (handle_t *, struct inode *, - const struct qstr *, umode_t); -extern void ext3_free_inode (handle_t *, struct inode *); -extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); -extern unsigned long ext3_count_free_inodes (struct super_block *); -extern unsigned long ext3_count_dirs (struct super_block *); -extern void ext3_check_inodes_bitmap (struct super_block *); -extern unsigned long ext3_count_free (struct buffer_head *, unsigned); - - -/* inode.c */ -int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, - struct buffer_head *bh, ext3_fsblk_t blocknr); -struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); -struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); -int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, - sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, - int create); - -extern struct inode *ext3_iget(struct super_block *, unsigned long); -extern int ext3_write_inode (struct inode *, struct writeback_control *); -extern int ext3_setattr (struct dentry *, struct iattr *); -extern void ext3_evict_inode (struct inode *); -extern int ext3_sync_inode (handle_t *, struct inode *); -extern void ext3_discard_reservation (struct inode *); -extern void ext3_dirty_inode(struct inode *, int); -extern int ext3_change_inode_journal_flag(struct inode *, int); -extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); -extern int ext3_can_truncate(struct inode *inode); -extern void ext3_truncate(struct inode *inode); -extern void ext3_set_inode_flags(struct inode *); -extern void ext3_get_inode_flags(struct ext3_inode_info *); -extern void ext3_set_aops(struct inode *inode); -extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, - u64 start, u64 len); - -/* ioctl.c */ -extern long ext3_ioctl(struct file *, unsigned int, unsigned long); -extern long ext3_compat_ioctl(struct file *, unsigned int, unsigned long); - -/* namei.c */ -extern int ext3_orphan_add(handle_t *, struct inode *); -extern int ext3_orphan_del(handle_t *, struct inode *); -extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, - __u32 start_minor_hash, __u32 *next_hash); - -/* resize.c */ -extern int ext3_group_add(struct super_block *sb, - struct ext3_new_group_data *input); -extern int ext3_group_extend(struct super_block *sb, - struct ext3_super_block *es, - ext3_fsblk_t n_blocks_count); - -/* super.c */ -extern __printf(3, 4) -void ext3_error(struct super_block *, const char *, const char *, ...); -extern void __ext3_std_error (struct super_block *, const char *, int); -extern __printf(3, 4) -void ext3_abort(struct super_block *, const char *, const char *, ...); -extern __printf(3, 4) -void ext3_warning(struct super_block *, const char *, const char *, ...); -extern __printf(3, 4) -void ext3_msg(struct super_block *, const char *, const char *, ...); -extern void ext3_update_dynamic_rev (struct super_block *sb); - -#define ext3_std_error(sb, errno) \ -do { \ - if ((errno)) \ - __ext3_std_error((sb), __func__, (errno)); \ -} while (0) - -/* - * Inodes and files operations - */ - -/* dir.c */ -extern const struct file_operations ext3_dir_operations; - -/* file.c */ -extern const struct inode_operations ext3_file_inode_operations; -extern const struct file_operations ext3_file_operations; - -/* namei.c */ -extern const struct inode_operations ext3_dir_inode_operations; -extern const struct inode_operations ext3_special_inode_operations; - -/* symlink.c */ -extern const struct inode_operations ext3_symlink_inode_operations; -extern const struct inode_operations ext3_fast_symlink_inode_operations; - -#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) - -/* Define the number of blocks we need to account to a transaction to - * modify one block of data. - * - * We may have to touch one inode, one bitmap buffer, up to three - * indirection blocks, the group and superblock summaries, and the data - * block to complete the transaction. */ - -#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U - -/* Extended attribute operations touch at most two data buffers, - * two bitmap buffers, and two group summaries, in addition to the inode - * and the superblock, which are already accounted for. */ - -#define EXT3_XATTR_TRANS_BLOCKS 6U - -/* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - -#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ - EXT3_XATTR_TRANS_BLOCKS - 2 + \ - EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) - -/* Delete operations potentially hit one directory's namespace plus an - * entire inode, plus arbitrary amounts of bitmap/indirection data. Be - * generous. We can grow the delete transaction later if necessary. */ - -#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) - -/* Define an arbitrary limit for the amount of data we will anticipate - * writing to any given transaction. For unbounded transactions such as - * write(2) and truncate(2) we can write more than this, but we always - * start off at the maximum transaction size and grow the transaction - * optimistically as we go. */ - -#define EXT3_MAX_TRANS_DATA 64U - -/* We break up a large truncate or write transaction once the handle's - * buffer credits gets this low, we need either to extend the - * transaction or to start a new one. Reserve enough space here for - * inode, bitmap, superblock, group and indirection updates for at least - * one block, plus two quota updates. Quota allocations are not - * needed. */ - -#define EXT3_RESERVE_TRANS_BLOCKS 12U - -#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 - -#ifdef CONFIG_QUOTA -/* Amount of blocks needed for quota update - we know that the structure was - * allocated so we need to update only inode+data */ -#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) -/* Amount of blocks needed for quota insert/delete - we do some block writes - * but inode, sb and group updates are done only once */ -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) -#else -#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 -#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 -#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 -#endif -#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) -#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) -#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) - -int -ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, - struct ext3_iloc *iloc); - -/* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. - */ - -int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, - struct ext3_iloc *iloc); - -int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); - -/* - * Wrapper functions with which ext3 calls into JBD. The intent here is - * to allow these to be turned into appropriate stubs so ext3 can control - * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't - * been done yet. - */ - -static inline void ext3_journal_release_buffer(handle_t *handle, - struct buffer_head *bh) -{ - journal_release_buffer(handle, bh); -} - -void ext3_journal_abort_handle(const char *caller, const char *err_fn, - struct buffer_head *bh, handle_t *handle, int err); - -int __ext3_journal_get_undo_access(const char *where, handle_t *handle, - struct buffer_head *bh); - -int __ext3_journal_get_write_access(const char *where, handle_t *handle, - struct buffer_head *bh); - -int __ext3_journal_forget(const char *where, handle_t *handle, - struct buffer_head *bh); - -int __ext3_journal_revoke(const char *where, handle_t *handle, - unsigned long blocknr, struct buffer_head *bh); - -int __ext3_journal_get_create_access(const char *where, - handle_t *handle, struct buffer_head *bh); - -int __ext3_journal_dirty_metadata(const char *where, - handle_t *handle, struct buffer_head *bh); - -#define ext3_journal_get_undo_access(handle, bh) \ - __ext3_journal_get_undo_access(__func__, (handle), (bh)) -#define ext3_journal_get_write_access(handle, bh) \ - __ext3_journal_get_write_access(__func__, (handle), (bh)) -#define ext3_journal_revoke(handle, blocknr, bh) \ - __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) -#define ext3_journal_get_create_access(handle, bh) \ - __ext3_journal_get_create_access(__func__, (handle), (bh)) -#define ext3_journal_dirty_metadata(handle, bh) \ - __ext3_journal_dirty_metadata(__func__, (handle), (bh)) -#define ext3_journal_forget(handle, bh) \ - __ext3_journal_forget(__func__, (handle), (bh)) - -int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); - -handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); -int __ext3_journal_stop(const char *where, handle_t *handle); - -static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) -{ - return ext3_journal_start_sb(inode->i_sb, nblocks); -} - -#define ext3_journal_stop(handle) \ - __ext3_journal_stop(__func__, (handle)) - -static inline handle_t *ext3_journal_current_handle(void) -{ - return journal_current_handle(); -} - -static inline int ext3_journal_extend(handle_t *handle, int nblocks) -{ - return journal_extend(handle, nblocks); -} - -static inline int ext3_journal_restart(handle_t *handle, int nblocks) -{ - return journal_restart(handle, nblocks); -} - -static inline int ext3_journal_blocks_per_page(struct inode *inode) -{ - return journal_blocks_per_page(inode); -} - -static inline int ext3_journal_force_commit(journal_t *journal) -{ - return journal_force_commit(journal); -} - -/* super.c */ -int ext3_force_commit(struct super_block *sb); - -static inline int ext3_should_journal_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 1; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) - return 1; - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 1; - return 0; -} - -static inline int ext3_should_order_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 0; - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 0; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) - return 1; - return 0; -} - -static inline int ext3_should_writeback_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 0; - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 0; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) - return 1; - return 0; -} - -#include - diff --git a/instrumentation/events/mainline/jbd.h b/instrumentation/events/mainline/jbd.h index aff64d8..da6f259 100644 --- a/instrumentation/events/mainline/jbd.h +++ b/instrumentation/events/mainline/jbd.h @@ -36,19 +36,17 @@ DECLARE_EVENT_CLASS(jbd_commit, TP_STRUCT__entry( __field( dev_t, dev ) - __field( char, sync_commit ) __field( int, transaction ) ), TP_fast_assign( __entry->dev = journal->j_fs_dev->bd_dev; - __entry->sync_commit = commit_transaction->t_synchronous_commit; __entry->transaction = commit_transaction->t_tid; ), - TP_printk("dev %d,%d transaction %d sync %d", + TP_printk("dev %d,%d transaction %d", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->transaction, __entry->sync_commit) + __entry->transaction) ); DEFINE_EVENT(jbd_commit, jbd_start_commit, @@ -87,19 +85,17 @@ TRACE_EVENT(jbd_drop_transaction, TP_STRUCT__entry( __field( dev_t, dev ) - __field( char, sync_commit ) __field( int, transaction ) ), TP_fast_assign( __entry->dev = journal->j_fs_dev->bd_dev; - __entry->sync_commit = commit_transaction->t_synchronous_commit; __entry->transaction = commit_transaction->t_tid; ), - TP_printk("dev %d,%d transaction %d sync %d", + TP_printk("dev %d,%d transaction %d", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->transaction, __entry->sync_commit) + __entry->transaction) ); TRACE_EVENT(jbd_end_commit, @@ -109,21 +105,19 @@ TRACE_EVENT(jbd_end_commit, TP_STRUCT__entry( __field( dev_t, dev ) - __field( char, sync_commit ) __field( int, transaction ) __field( int, head ) ), TP_fast_assign( __entry->dev = journal->j_fs_dev->bd_dev; - __entry->sync_commit = commit_transaction->t_synchronous_commit; __entry->transaction = commit_transaction->t_tid; __entry->head = journal->j_tail_sequence; ), - TP_printk("dev %d,%d transaction %d sync %d head %d", + TP_printk("dev %d,%d transaction %d head %d", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->transaction, __entry->sync_commit, __entry->head) + __entry->transaction, __entry->head) ); TRACE_EVENT(jbd_do_submit_data, @@ -133,19 +127,17 @@ TRACE_EVENT(jbd_do_submit_data, TP_STRUCT__entry( __field( dev_t, dev ) - __field( char, sync_commit ) __field( int, transaction ) ), TP_fast_assign( __entry->dev = journal->j_fs_dev->bd_dev; - __entry->sync_commit = commit_transaction->t_synchronous_commit; __entry->transaction = commit_transaction->t_tid; ), - TP_printk("dev %d,%d transaction %d sync %d", + TP_printk("dev %d,%d transaction %d", MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->transaction, __entry->sync_commit) + __entry->transaction) ); TRACE_EVENT(jbd_cleanup_journal_tail, @@ -177,24 +169,23 @@ TRACE_EVENT(jbd_cleanup_journal_tail, __entry->block_nr, __entry->freed) ); -TRACE_EVENT(jbd_update_superblock_end, - TP_PROTO(journal_t *journal, int wait), +TRACE_EVENT(journal_write_superblock, + TP_PROTO(journal_t *journal, int write_op), - TP_ARGS(journal, wait), + TP_ARGS(journal, write_op), TP_STRUCT__entry( __field( dev_t, dev ) - __field( int, wait ) + __field( int, write_op ) ), TP_fast_assign( __entry->dev = journal->j_fs_dev->bd_dev; - __entry->wait = wait; + __entry->write_op = write_op; ), - TP_printk("dev %d,%d wait %d", - MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->wait) + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), + MINOR(__entry->dev), __entry->write_op) ); #endif /* _TRACE_JBD_H */ diff --git a/instrumentation/events/mainline/jbd2.h b/instrumentation/events/mainline/jbd2.h index 7596441..127993d 100644 --- a/instrumentation/events/mainline/jbd2.h +++ b/instrumentation/events/mainline/jbd2.h @@ -81,6 +81,13 @@ DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, TP_ARGS(journal, commit_transaction) ); +DEFINE_EVENT(jbd2_commit, jbd2_drop_transaction, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction) +); + TRACE_EVENT(jbd2_end_commit, TP_PROTO(journal_t *journal, transaction_t *commit_transaction), @@ -200,7 +207,7 @@ TRACE_EVENT(jbd2_checkpoint_stats, __entry->forced_to_close, __entry->written, __entry->dropped) ); -TRACE_EVENT(jbd2_cleanup_journal_tail, +TRACE_EVENT(jbd2_update_log_tail, TP_PROTO(journal_t *journal, tid_t first_tid, unsigned long block_nr, unsigned long freed), @@ -229,6 +236,26 @@ TRACE_EVENT(jbd2_cleanup_journal_tail, __entry->block_nr, __entry->freed) ); +TRACE_EVENT(jbd2_write_superblock, + + TP_PROTO(journal_t *journal, int write_op), + + TP_ARGS(journal, write_op), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, write_op ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->write_op = write_op; + ), + + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), + MINOR(__entry->dev), __entry->write_op) +); + #endif /* _TRACE_JBD2_H */ /* This part must be outside protection */ diff --git a/instrumentation/events/mainline/kmem.h b/instrumentation/events/mainline/kmem.h index a9c87ad..08fa272 100644 --- a/instrumentation/events/mainline/kmem.h +++ b/instrumentation/events/mainline/kmem.h @@ -147,7 +147,7 @@ DEFINE_EVENT(kmem_free, kmem_cache_free, TP_ARGS(call_site, ptr) ); -TRACE_EVENT(mm_page_free_direct, +TRACE_EVENT(mm_page_free, TP_PROTO(struct page *page, unsigned int order), @@ -169,7 +169,7 @@ TRACE_EVENT(mm_page_free_direct, __entry->order) ); -TRACE_EVENT(mm_pagevec_free, +TRACE_EVENT(mm_page_free_batched, TP_PROTO(struct page *page, int cold), @@ -214,7 +214,7 @@ TRACE_EVENT(mm_page_alloc, TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", __entry->page, - page_to_pfn(__entry->page), + __entry->page ? page_to_pfn(__entry->page) : 0, __entry->order, __entry->migratetype, show_gfp_flags(__entry->gfp_flags)) @@ -240,7 +240,7 @@ DECLARE_EVENT_CLASS(mm_page, TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", __entry->page, - page_to_pfn(__entry->page), + __entry->page ? page_to_pfn(__entry->page) : 0, __entry->order, __entry->migratetype, __entry->order == 0) diff --git a/instrumentation/events/mainline/power.h b/instrumentation/events/mainline/power.h index 1bcc2a8..0c97838 100644 --- a/instrumentation/events/mainline/power.h +++ b/instrumentation/events/mainline/power.h @@ -65,7 +65,40 @@ TRACE_EVENT(machine_suspend, TP_printk("state=%lu", (unsigned long)__entry->state) ); -/* This code will be removed after deprecation time exceeded (2.6.41) */ +DECLARE_EVENT_CLASS(wakeup_source, + + TP_PROTO(const char *name, unsigned int state), + + TP_ARGS(name, state), + + TP_STRUCT__entry( + __string( name, name ) + __field( u64, state ) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->state = state; + ), + + TP_printk("%s state=0x%lx", __get_str(name), + (unsigned long)__entry->state) +); + +DEFINE_EVENT(wakeup_source, wakeup_source_activate, + + TP_PROTO(const char *name, unsigned int state), + + TP_ARGS(name, state) +); + +DEFINE_EVENT(wakeup_source, wakeup_source_deactivate, + + TP_PROTO(const char *name, unsigned int state), + + TP_ARGS(name, state) +); + #ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED /* @@ -151,6 +184,8 @@ enum { events get removed */ static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; static inline void trace_power_end(u64 cpuid) {}; +static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {}; +static inline void trace_power_end_rcuidle(u64 cpuid) {}; static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; #endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ diff --git a/instrumentation/events/mainline/sched.h b/instrumentation/events/mainline/sched.h index 6700ecc..ea7a203 100644 --- a/instrumentation/events/mainline/sched.h +++ b/instrumentation/events/mainline/sched.h @@ -6,6 +6,7 @@ #include #include +#include /* * Tracepoint for calling kthread_stop, performed to end a kthread: @@ -100,7 +101,7 @@ static inline long __trace_sched_switch_state(struct task_struct *p) * For all intents and purposes a preempted task is a running task. */ if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) - state = TASK_RUNNING; + state = TASK_RUNNING | TASK_STATE_MAX; #endif return state; @@ -137,13 +138,14 @@ TRACE_EVENT(sched_switch, __entry->next_prio = next->prio; ), - TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_pid=%d next_prio=%d", + TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, - __entry->prev_state ? - __print_flags(__entry->prev_state, "|", + __entry->prev_state & (TASK_STATE_MAX-1) ? + __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|", { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, { 16, "Z" }, { 32, "X" }, { 64, "x" }, { 128, "W" }) : "R", + __entry->prev_state & TASK_STATE_MAX ? "+" : "", __entry->next_comm, __entry->next_pid, __entry->next_prio) ); @@ -356,6 +358,13 @@ DEFINE_EVENT(sched_stat_template, sched_stat_iowait, TP_ARGS(tsk, delay)); /* + * Tracepoint for accounting blocked time (time the task is in uninterruptible). + */ +DEFINE_EVENT(sched_stat_template, sched_stat_blocked, + TP_PROTO(struct task_struct *tsk, u64 delay), + TP_ARGS(tsk, delay)); + +/* * Tracepoint for accounting runtime (time the task is executing * on a CPU). */ diff --git a/instrumentation/events/mainline/signal.h b/instrumentation/events/mainline/signal.h index 17df434..39a8a43 100644 --- a/instrumentation/events/mainline/signal.h +++ b/instrumentation/events/mainline/signal.h @@ -23,11 +23,23 @@ } \ } while (0) +#ifndef TRACE_HEADER_MULTI_READ +enum { + TRACE_SIGNAL_DELIVERED, + TRACE_SIGNAL_IGNORED, + TRACE_SIGNAL_ALREADY_PENDING, + TRACE_SIGNAL_OVERFLOW_FAIL, + TRACE_SIGNAL_LOSE_INFO, +}; +#endif + /** * signal_generate - called when a signal is generated * @sig: signal number * @info: pointer to struct siginfo * @task: pointer to struct task_struct + * @group: shared or private + * @result: TRACE_SIGNAL_* * * Current process sends a 'sig' signal to 'task' process with * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV, @@ -37,9 +49,10 @@ */ TRACE_EVENT(signal_generate, - TP_PROTO(int sig, struct siginfo *info, struct task_struct *task), + TP_PROTO(int sig, struct siginfo *info, struct task_struct *task, + int group, int result), - TP_ARGS(sig, info, task), + TP_ARGS(sig, info, task, group, result), TP_STRUCT__entry( __field( int, sig ) @@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate, __field( int, code ) __array( char, comm, TASK_COMM_LEN ) __field( pid_t, pid ) + __field( int, group ) + __field( int, result ) ), TP_fast_assign( @@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate, TP_STORE_SIGINFO(__entry, info); memcpy(__entry->comm, task->comm, TASK_COMM_LEN); __entry->pid = task->pid; + __entry->group = group; + __entry->result = result; ), - TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d", + TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d", __entry->sig, __entry->errno, __entry->code, - __entry->comm, __entry->pid) + __entry->comm, __entry->pid, __entry->group, + __entry->result) ); /** @@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver, __entry->sa_handler, __entry->sa_flags) ); -DECLARE_EVENT_CLASS(signal_queue_overflow, - - TP_PROTO(int sig, int group, struct siginfo *info), - - TP_ARGS(sig, group, info), - - TP_STRUCT__entry( - __field( int, sig ) - __field( int, group ) - __field( int, errno ) - __field( int, code ) - ), - - TP_fast_assign( - __entry->sig = sig; - __entry->group = group; - TP_STORE_SIGINFO(__entry, info); - ), - - TP_printk("sig=%d group=%d errno=%d code=%d", - __entry->sig, __entry->group, __entry->errno, __entry->code) -); - -/** - * signal_overflow_fail - called when signal queue is overflow - * @sig: signal number - * @group: signal to process group or not (bool) - * @info: pointer to struct siginfo - * - * Kernel fails to generate 'sig' signal with 'info' siginfo, because - * siginfo queue is overflow, and the signal is dropped. - * 'group' is not 0 if the signal will be sent to a process group. - * 'sig' is always one of RT signals. - */ -DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail, - - TP_PROTO(int sig, int group, struct siginfo *info), - - TP_ARGS(sig, group, info) -); - -/** - * signal_lose_info - called when siginfo is lost - * @sig: signal number - * @group: signal to process group or not (bool) - * @info: pointer to struct siginfo - * - * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo - * queue is overflow. - * 'group' is not 0 if the signal will be sent to a process group. - * 'sig' is always one of non-RT signals. - */ -DEFINE_EVENT(signal_queue_overflow, signal_lose_info, - - TP_PROTO(int sig, int group, struct siginfo *info), - - TP_ARGS(sig, group, info) -); - #endif /* _TRACE_SIGNAL_H */ /* This part must be outside protection */ diff --git a/instrumentation/events/mainline/vmscan.h b/instrumentation/events/mainline/vmscan.h index 36851f7..bab3b87 100644 --- a/instrumentation/events/mainline/vmscan.h +++ b/instrumentation/events/mainline/vmscan.h @@ -13,7 +13,7 @@ #define RECLAIM_WB_ANON 0x0001u #define RECLAIM_WB_FILE 0x0002u #define RECLAIM_WB_MIXED 0x0010u -#define RECLAIM_WB_SYNC 0x0004u +#define RECLAIM_WB_SYNC 0x0004u /* Unused, all reclaim async */ #define RECLAIM_WB_ASYNC 0x0008u #define show_reclaim_flags(flags) \ @@ -25,15 +25,15 @@ {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ ) : "RECLAIM_WB_NONE" -#define trace_reclaim_flags(page, sync) ( \ +#define trace_reclaim_flags(page) ( \ (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ - (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ + (RECLAIM_WB_ASYNC) \ ) -#define trace_shrink_flags(file, sync) ( \ - (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ - (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ - (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ +#define trace_shrink_flags(file) \ + ( \ + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ + (RECLAIM_WB_ASYNC) \ ) TRACE_EVENT(mm_vmscan_kswapd_sleep, @@ -263,22 +263,18 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, unsigned long nr_requested, unsigned long nr_scanned, unsigned long nr_taken, - unsigned long nr_lumpy_taken, - unsigned long nr_lumpy_dirty, - unsigned long nr_lumpy_failed, - int isolate_mode), + isolate_mode_t isolate_mode, + int file), - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file), TP_STRUCT__entry( __field(int, order) __field(unsigned long, nr_requested) __field(unsigned long, nr_scanned) __field(unsigned long, nr_taken) - __field(unsigned long, nr_lumpy_taken) - __field(unsigned long, nr_lumpy_dirty) - __field(unsigned long, nr_lumpy_failed) - __field(int, isolate_mode) + __field(isolate_mode_t, isolate_mode) + __field(int, file) ), TP_fast_assign( @@ -286,21 +282,17 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, __entry->nr_requested = nr_requested; __entry->nr_scanned = nr_scanned; __entry->nr_taken = nr_taken; - __entry->nr_lumpy_taken = nr_lumpy_taken; - __entry->nr_lumpy_dirty = nr_lumpy_dirty; - __entry->nr_lumpy_failed = nr_lumpy_failed; __entry->isolate_mode = isolate_mode; + __entry->file = file; ), - TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d", __entry->isolate_mode, __entry->order, __entry->nr_requested, __entry->nr_scanned, __entry->nr_taken, - __entry->nr_lumpy_taken, - __entry->nr_lumpy_dirty, - __entry->nr_lumpy_failed) + __entry->file) ); DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, @@ -309,12 +301,10 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, unsigned long nr_requested, unsigned long nr_scanned, unsigned long nr_taken, - unsigned long nr_lumpy_taken, - unsigned long nr_lumpy_dirty, - unsigned long nr_lumpy_failed, - int isolate_mode), + isolate_mode_t isolate_mode, + int file), - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) ); @@ -324,12 +314,10 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, unsigned long nr_requested, unsigned long nr_scanned, unsigned long nr_taken, - unsigned long nr_lumpy_taken, - unsigned long nr_lumpy_dirty, - unsigned long nr_lumpy_failed, - int isolate_mode), + isolate_mode_t isolate_mode, + int file), - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) ); @@ -389,88 +377,6 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, show_reclaim_flags(__entry->reclaim_flags)) ); -TRACE_EVENT(replace_swap_token, - TP_PROTO(struct mm_struct *old_mm, - struct mm_struct *new_mm), - - TP_ARGS(old_mm, new_mm), - - TP_STRUCT__entry( - __field(struct mm_struct*, old_mm) - __field(unsigned int, old_prio) - __field(struct mm_struct*, new_mm) - __field(unsigned int, new_prio) - ), - - TP_fast_assign( - __entry->old_mm = old_mm; - __entry->old_prio = old_mm ? old_mm->token_priority : 0; - __entry->new_mm = new_mm; - __entry->new_prio = new_mm->token_priority; - ), - - TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", - __entry->old_mm, __entry->old_prio, - __entry->new_mm, __entry->new_prio) -); - -DECLARE_EVENT_CLASS(put_swap_token_template, - TP_PROTO(struct mm_struct *swap_token_mm), - - TP_ARGS(swap_token_mm), - - TP_STRUCT__entry( - __field(struct mm_struct*, swap_token_mm) - ), - - TP_fast_assign( - __entry->swap_token_mm = swap_token_mm; - ), - - TP_printk("token_mm=%p", __entry->swap_token_mm) -); - -DEFINE_EVENT(put_swap_token_template, put_swap_token, - TP_PROTO(struct mm_struct *swap_token_mm), - TP_ARGS(swap_token_mm) -); - -DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, - TP_PROTO(struct mm_struct *swap_token_mm), - TP_ARGS(swap_token_mm), - TP_CONDITION(swap_token_mm != NULL) -); - -TRACE_EVENT_CONDITION(update_swap_token_priority, - TP_PROTO(struct mm_struct *mm, - unsigned int old_prio, - struct mm_struct *swap_token_mm), - - TP_ARGS(mm, old_prio, swap_token_mm), - - TP_CONDITION(mm->token_priority != old_prio), - - TP_STRUCT__entry( - __field(struct mm_struct*, mm) - __field(unsigned int, old_prio) - __field(unsigned int, new_prio) - __field(struct mm_struct*, swap_token_mm) - __field(unsigned int, swap_token_prio) - ), - - TP_fast_assign( - __entry->mm = mm; - __entry->old_prio = old_prio; - __entry->new_prio = mm->token_priority; - __entry->swap_token_mm = swap_token_mm; - __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0; - ), - - TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", - __entry->mm, __entry->old_prio, __entry->new_prio, - __entry->swap_token_mm, __entry->swap_token_prio) -); - #endif /* _TRACE_VMSCAN_H */ /* This part must be outside protection */ diff --git a/probes/Makefile b/probes/Makefile index c39a84a..ca5a9d6 100644 --- a/probes/Makefile +++ b/probes/Makefile @@ -37,10 +37,13 @@ endif endif ifneq ($(CONFIG_NET),) -obj-m += lttng-probe-net.o obj-m += lttng-probe-napi.o obj-m += lttng-probe-skb.o obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 37 \) ] ; then \ + echo "lttng-probe-net.o" ; fi;) +obj-m += $(shell \ if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ echo "lttng-probe-sock.o" ; fi;) obj-m += $(shell \ @@ -86,12 +89,14 @@ endif ifneq ($(CONFIG_SCSI),) obj-m += $(shell \ - if [ $(VERSION) -ge 3 ] ; then \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 35 \) ] ; then \ echo "lttng-probe-scsi.o" ; fi;) endif vmscan = $(shell \ - if [ $(VERSION) -ge 3 ] ; then \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ echo "lttng-probe-vmscan.o" ; fi;) ifneq ($(CONFIG_SWAP),) obj-m += $(vmscan) @@ -102,7 +107,10 @@ endif endif ifneq ($(CONFIG_LOCKDEP),) -obj-m += lttng-probe-lock.o +obj-m += $(shell \ + if [ $(VERSION) -ge 3 \ + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 35 \) ] ; then \ + echo "lttng-probe-lock.o" ; fi;) endif ifneq ($(CONFIG_KPROBES),) diff --git a/probes/lttng-probe-asoc.c b/probes/lttng-probe-asoc.c index 427639f..f1981a0 100644 --- a/probes/lttng-probe-asoc.c +++ b/probes/lttng-probe-asoc.c @@ -1,5 +1,5 @@ /* - * probes/lttng-probe-block.c + * probes/lttng-probe-asoc.c * * LTTng asoc probes. * diff --git a/probes/lttng-probe-ext3.c b/probes/lttng-probe-ext3.c index 0df2b67..d5842e1 100644 --- a/probes/lttng-probe-ext3.c +++ b/probes/lttng-probe-ext3.c @@ -27,20 +27,16 @@ #include #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) -/* - * Since 3.4 the is no linux/ext3_fs_i.h anymore. Instead we have to use - * ext3.h from fs/ext3/ext3.h (which also includes trace/events/ext3.h) - */ -#include "../instrumentation/events/mainline/fs_ext3.h" +#include <../fs/ext3/ext3.h> #else #include +#endif /* * Create the tracepoint static inlines from the kernel to validate that our * trace event macros match the kernel we run on. */ #include -#endif /* * Create LTTng tracepoint probes. diff --git a/probes/lttng-probe-jbd.c b/probes/lttng-probe-jbd.c index 46911cc..9bac325 100644 --- a/probes/lttng-probe-jbd.c +++ b/probes/lttng-probe-jbd.c @@ -22,7 +22,6 @@ */ #include -#include /* * Create the tracepoint static inlines from the kernel to validate that our diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c index 4f5739c..b78c0d6 100644 --- a/probes/lttng-probe-vmscan.c +++ b/probes/lttng-probe-vmscan.c @@ -22,7 +22,6 @@ */ #include -#include /* * Create the tracepoint static inlines from the kernel to validate that our @@ -39,11 +38,6 @@ #define CREATE_TRACE_POINTS #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module -#if ((LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ - LTTNG_KERNEL_RANGE(3,1,0, 3,2,0)) -typedef int isolate_mode_t; -#endif - #include "../instrumentation/events/lttng-module/vmscan.h" MODULE_LICENSE("GPL and additional rights"); -- 1.7.10.4 From andrew_gabbasov at mentor.com Wed Nov 28 09:43:26 2012 From: andrew_gabbasov at mentor.com (Andrew Gabbasov) Date: Wed, 28 Nov 2012 08:43:26 -0600 Subject: [lttng-dev] [PATCH lttng-tools] Fix a typo in lttng-probe-module name Message-ID: <1354113806-19089-1-git-send-email-andrew_gabbasov@mentor.com> Signed-off-by: Andrew Gabbasov --- src/bin/lttng-sessiond/modprobe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c index f38d393..8e5cc94 100644 --- a/src/bin/lttng-sessiond/modprobe.c +++ b/src/bin/lttng-sessiond/modprobe.c @@ -54,7 +54,7 @@ const struct kern_modules_param kern_modules_list[] = { { "lttng-probe-kmem", 0 }, { "lttng-probe-kvm", 0 }, { "lttng-probe-lock", 0 }, - { "lttng-probe-modules", 0 }, + { "lttng-probe-module", 0 }, { "lttng-probe-napi", 0 }, { "lttng-probe-net", 0 }, { "lttng-probe-power", 0 }, -- 1.7.10.4 From jbernard at tuxion.com Wed Nov 28 10:13:59 2012 From: jbernard at tuxion.com (Jon Bernard) Date: Wed, 28 Nov 2012 10:13:59 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Link test utilities against urcu-bp Message-ID: <20121128151359.GA2051@quintessa> The gen-ust-events utility used in several of the tests references the 'rcu_dereference_sym' symbol contained in urcu-bp. It is necessary to link against urcu-bp so that this symbol is resolved. Signed-off-by: Jon Bernard --- tests/tools/filtering/Makefile.am | 2 +- tests/tools/streaming/Makefile.am | 2 +- tests/ust/before-after/Makefile.am | 2 +- tests/ust/high-throughput/Makefile.am | 2 +- tests/ust/multi-session/Makefile.am | 2 +- tests/ust/nprocesses/Makefile.am | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/tools/filtering/Makefile.am b/tests/tools/filtering/Makefile.am index e1e715d..287effc 100644 --- a/tests/tools/filtering/Makefile.am +++ b/tests/tools/filtering/Makefile.am @@ -11,7 +11,7 @@ endif if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS = gen-ust-events gen_ust_events_SOURCES = gen-ust-events.c tp.c tp.h -gen_ust_events_LDADD = -llttng-ust +gen_ust_events_LDADD = -llttng-ust -lurcu-bp endif noinst_SCRIPTS = runall unsupported-ops invalid-filters valid-filters babelstats.pl diff --git a/tests/tools/streaming/Makefile.am b/tests/tools/streaming/Makefile.am index 3ff8ef0..d07baa8 100644 --- a/tests/tools/streaming/Makefile.am +++ b/tests/tools/streaming/Makefile.am @@ -20,7 +20,7 @@ unit_tests_LDADD = $(LIBCOMMON) if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += gen-ust-events gen_ust_events_SOURCES = gen-ust-events.c tp.c tp.h -gen_ust_events_LDADD = -llttng-ust +gen_ust_events_LDADD = -llttng-ust -lurcu-bp endif noinst_SCRIPTS = runall run-ust run-kernel uri_switch diff --git a/tests/ust/before-after/Makefile.am b/tests/ust/before-after/Makefile.am index d197d72..80a6ba2 100644 --- a/tests/ust/before-after/Makefile.am +++ b/tests/ust/before-after/Makefile.am @@ -10,7 +10,7 @@ endif noinst_PROGRAMS = gen-nevents gen_nevents_SOURCES = gen-nevents.c tp.c ust_gen_nevents.h -gen_nevents_LDADD = -llttng-ust +gen_nevents_LDADD = -llttng-ust -lurcu-bp noinst_SCRIPTS = run EXTRA_DIST = run diff --git a/tests/ust/high-throughput/Makefile.am b/tests/ust/high-throughput/Makefile.am index cff8fe4..74478bd 100644 --- a/tests/ust/high-throughput/Makefile.am +++ b/tests/ust/high-throughput/Makefile.am @@ -10,7 +10,7 @@ endif noinst_PROGRAMS = gen-events gen_events_SOURCES = main.c tp.c tp.h -gen_events_LDADD = -llttng-ust +gen_events_LDADD = -llttng-ust -lurcu-bp noinst_SCRIPTS = run EXTRA_DIST = run diff --git a/tests/ust/multi-session/Makefile.am b/tests/ust/multi-session/Makefile.am index d197d72..80a6ba2 100644 --- a/tests/ust/multi-session/Makefile.am +++ b/tests/ust/multi-session/Makefile.am @@ -10,7 +10,7 @@ endif noinst_PROGRAMS = gen-nevents gen_nevents_SOURCES = gen-nevents.c tp.c ust_gen_nevents.h -gen_nevents_LDADD = -llttng-ust +gen_nevents_LDADD = -llttng-ust -lurcu-bp noinst_SCRIPTS = run EXTRA_DIST = run diff --git a/tests/ust/nprocesses/Makefile.am b/tests/ust/nprocesses/Makefile.am index 20beea0..bc3a503 100644 --- a/tests/ust/nprocesses/Makefile.am +++ b/tests/ust/nprocesses/Makefile.am @@ -10,7 +10,7 @@ endif noinst_PROGRAMS = gen-events-time gen_events_time_SOURCES = gen-events-time.c tp.c ust_gen_event.h -gen_events_time_LDADD = -llttng-ust +gen_events_time_LDADD = -llttng-ust -lurcu-bp noinst_SCRIPTS = run EXTRA_DIST = run -- 1.8.0 From mathieu.desnoyers at efficios.com Wed Nov 28 10:50:32 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 28 Nov 2012 10:50:32 -0500 Subject: [lttng-dev] [PATCH lttng-modules] Update kernel probes to more detailed match to kernel versions In-Reply-To: <1354096526-22098-1-git-send-email-andrew_gabbasov@mentor.com> References: <1354096526-22098-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121128155032.GA9266@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > We have added some more ifdef's to kernel probes to more closely match > the kernel tracepoints for different kernel versions. The changes cover > kernel versions from 2.6.38 up to 3.7. We did not track the earlier > versions, and they are filtered out in probes Makefile. > > ext3 probe was modified to use #include <../fs/ext3/ext3.h> instead of > copying this include from kernel source to lttng-modules source. > Using such includes (there will be more similar in other probes) > imposes a restriction to use the full kernel source for building > lttng-modules rather than having just kernel "include" directory, > but it looks like full source is required anyway, at least with respect > to Makefiles structure. May be it is worth mentioning somewhere > in the documentation. > > The code was verified to compile with latest versions in all stable > branches from 2.6.38.x to 3.6.x and 3.7-rc7. I get this build failure on 3.5 with this patch: CC [M] /home/compudj/work/lttng-modules/probes/lttng-probe-ext3.o /home/compudj/work/lttng-modules/probes/lttng-probe-ext3.c:30:29: fatal error: ../fs/ext3/ext3.h: No such file or directory compilation terminated. can you look into it and submit a revised patch ? Also, although the README file states that we support only 3.6.38+, we happen to also have support for kernels down to 2.6.32 with the patches in the linux-patches/ directory applied to the appropriate kernel versions. So it would be good that the instrumentation compiles for those older kernels too. I promise we won't go further back than 2.6.32 though. Thanks, Mathieu > > Thanks. > > Best regards, > Andrew Gabbasov > > The actual patch is below. > > > >From 81b2f45837cba1e258a79fad6b8b33474d968198 Mon Sep 17 00:00:00 2001 > From: Andrew Gabbasov > Date: Sat, 24 Nov 2012 14:50:09 -0600 > Subject: [PATCH lttng-modules] Update kernel probes to more detailed match to > kernel versions > > Some ifdef's are added to kernel probes instrumentation to make them > more close to original tracepoints in different kernel versions. > > Signed-off-by: Andrew Gabbasov > --- > instrumentation/events/lttng-module/asoc.h | 82 ++ > instrumentation/events/lttng-module/block.h | 25 + > instrumentation/events/lttng-module/ext3.h | 6 + > instrumentation/events/lttng-module/jbd.h | 22 + > instrumentation/events/lttng-module/jbd2.h | 36 + > instrumentation/events/lttng-module/kmem.h | 17 +- > instrumentation/events/lttng-module/power.h | 42 +- > instrumentation/events/lttng-module/sched.h | 37 + > instrumentation/events/lttng-module/scsi.h | 37 + > instrumentation/events/lttng-module/signal.h | 2 + > instrumentation/events/lttng-module/vmscan.h | 138 ++- > instrumentation/events/mainline/asoc.h | 80 ++ > instrumentation/events/mainline/block.h | 20 +- > instrumentation/events/mainline/ext3.h | 4 +- > instrumentation/events/mainline/fs_ext3.h | 1323 -------------------------- > instrumentation/events/mainline/jbd.h | 39 +- > instrumentation/events/mainline/jbd2.h | 29 +- > instrumentation/events/mainline/kmem.h | 8 +- > instrumentation/events/mainline/power.h | 37 +- > instrumentation/events/mainline/sched.h | 17 +- > instrumentation/events/mainline/signal.h | 85 +- > instrumentation/events/mainline/vmscan.h | 136 +-- > probes/Makefile | 16 +- > probes/lttng-probe-asoc.c | 2 +- > probes/lttng-probe-ext3.c | 8 +- > probes/lttng-probe-jbd.c | 1 - > probes/lttng-probe-vmscan.c | 6 - > 27 files changed, 665 insertions(+), 1590 deletions(-) > delete mode 100644 instrumentation/events/mainline/fs_ext3.h > > diff --git a/instrumentation/events/lttng-module/asoc.h b/instrumentation/events/lttng-module/asoc.h > index 6ffc923..672bea4 100644 > --- a/instrumentation/events/lttng-module/asoc.h > +++ b/instrumentation/events/lttng-module/asoc.h > @@ -8,6 +8,8 @@ > #include > #include > > +#define DAPM_DIRECT "(direct)" > + > #ifndef _TRACE_ASOC_DEF > #define _TRACE_ASOC_DEF > struct snd_soc_jack; > @@ -251,6 +253,86 @@ TRACE_EVENT(snd_soc_dapm_walk_done, > ) > #endif > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) > +TRACE_EVENT(snd_soc_dapm_output_path, > + > + TP_PROTO(struct snd_soc_dapm_widget *widget, > + struct snd_soc_dapm_path *path), > + > + TP_ARGS(widget, path), > + > + TP_STRUCT__entry( > + __string( wname, widget->name ) > + __string( pname, path->name ? path->name : DAPM_DIRECT) > + __string( psname, path->sink->name ) > + __field( int, path_sink ) > + __field( int, path_connect ) > + ), > + > + TP_fast_assign( > + tp_strcpy(wname, widget->name) > + tp_strcpy(pname, path->name ? path->name : DAPM_DIRECT) > + tp_strcpy(psname, path->sink->name) > + tp_assign(path_connect, path->connect) > + tp_assign(path_sink, (long)path->sink) > + ), > + > + TP_printk("%c%s -> %s -> %s\n", > + (int) __entry->path_sink && > + (int) __entry->path_connect ? '*' : ' ', > + __get_str(wname), __get_str(pname), __get_str(psname)) > +) > + > +TRACE_EVENT(snd_soc_dapm_input_path, > + > + TP_PROTO(struct snd_soc_dapm_widget *widget, > + struct snd_soc_dapm_path *path), > + > + TP_ARGS(widget, path), > + > + TP_STRUCT__entry( > + __string( wname, widget->name ) > + __string( pname, path->name ? path->name : DAPM_DIRECT) > + __string( psname, path->source->name ) > + __field( int, path_source ) > + __field( int, path_connect ) > + ), > + > + TP_fast_assign( > + tp_strcpy(wname, widget->name) > + tp_strcpy(pname, path->name ? path->name : DAPM_DIRECT) > + tp_strcpy(psname, path->source->name) > + tp_assign(path_connect, path->connect) > + tp_assign(path_source, (long)path->source) > + ), > + > + TP_printk("%c%s <- %s <- %s\n", > + (int) __entry->path_source && > + (int) __entry->path_connect ? '*' : ' ', > + __get_str(wname), __get_str(pname), __get_str(psname)) > +) > + > +TRACE_EVENT(snd_soc_dapm_connected, > + > + TP_PROTO(int paths, int stream), > + > + TP_ARGS(paths, stream), > + > + TP_STRUCT__entry( > + __field( int, paths ) > + __field( int, stream ) > + ), > + > + TP_fast_assign( > + tp_assign(paths, paths) > + tp_assign(stream, stream) > + ), > + > + TP_printk("%s: found %d paths\n", > + __entry->stream ? "capture" : "playback", __entry->paths) > +) > +#endif > + > TRACE_EVENT(snd_soc_jack_irq, > > TP_PROTO(const char *name), > diff --git a/instrumentation/events/lttng-module/block.h b/instrumentation/events/lttng-module/block.h > index 42184f3..af34544 100644 > --- a/instrumentation/events/lttng-module/block.h > +++ b/instrumentation/events/lttng-module/block.h > @@ -8,6 +8,9 @@ > #include > #include > #include > +#include > + > +#define RWBS_LEN 8 > > #ifndef _TRACE_BLOCK_DEF_ > #define _TRACE_BLOCK_DEF_ > @@ -22,20 +25,40 @@ enum { > RWBS_FLAG_SYNC = (1 << 4), > RWBS_FLAG_META = (1 << 5), > RWBS_FLAG_SECURE = (1 << 6), > + RWBS_FLAG_FLUSH = (1 << 7), > + RWBS_FLAG_FUA = (1 << 8), > }; > > #endif /* _TRACE_BLOCK_DEF_ */ > > #define __print_rwbs_flags(rwbs) \ > __print_flags(rwbs, "", \ > + { RWBS_FLAG_FLUSH, "F" }, \ > { RWBS_FLAG_WRITE, "W" }, \ > { RWBS_FLAG_DISCARD, "D" }, \ > { RWBS_FLAG_READ, "R" }, \ > + { RWBS_FLAG_FUA, "F" }, \ > { RWBS_FLAG_RAHEAD, "A" }, \ > { RWBS_FLAG_SYNC, "S" }, \ > { RWBS_FLAG_META, "M" }, \ > { RWBS_FLAG_SECURE, "E" }) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) > + > +#define blk_fill_rwbs(rwbs, rw, bytes) \ > + tp_assign(rwbs, ((rw) & WRITE ? RWBS_FLAG_WRITE : \ > + ( (rw) & REQ_DISCARD ? RWBS_FLAG_DISCARD : \ > + ( (bytes) ? RWBS_FLAG_READ : \ > + ( 0 )))) \ > + | ((rw) & REQ_RAHEAD ? RWBS_FLAG_RAHEAD : 0) \ > + | ((rw) & REQ_SYNC ? RWBS_FLAG_SYNC : 0) \ > + | ((rw) & REQ_META ? RWBS_FLAG_META : 0) \ > + | ((rw) & REQ_SECURE ? RWBS_FLAG_SECURE : 0) \ > + | ((rw) & REQ_FLUSH ? RWBS_FLAG_FLUSH : 0) \ > + | ((rw) & REQ_FUA ? RWBS_FLAG_FUA : 0)) > + > +#else > + > #define blk_fill_rwbs(rwbs, rw, bytes) \ > tp_assign(rwbs, ((rw) & WRITE ? RWBS_FLAG_WRITE : \ > ( (rw) & REQ_DISCARD ? RWBS_FLAG_DISCARD : \ > @@ -46,6 +69,8 @@ enum { > | ((rw) & REQ_META ? RWBS_FLAG_META : 0) \ > | ((rw) & REQ_SECURE ? RWBS_FLAG_SECURE : 0)) > > +#endif > + > DECLARE_EVENT_CLASS(block_rq_with_error, > > TP_PROTO(struct request_queue *q, struct request *rq), > diff --git a/instrumentation/events/lttng-module/ext3.h b/instrumentation/events/lttng-module/ext3.h > index f1b4aa9..32917fb 100644 > --- a/instrumentation/events/lttng-module/ext3.h > +++ b/instrumentation/events/lttng-module/ext3.h > @@ -5,6 +5,7 @@ > #define _TRACE_EXT3_H > > #include > +#include > > TRACE_EVENT(ext3_free_inode, > TP_PROTO(struct inode *inode), > @@ -24,8 +25,13 @@ TRACE_EVENT(ext3_free_inode, > tp_assign(dev, inode->i_sb->s_dev) > tp_assign(ino, inode->i_ino) > tp_assign(mode, inode->i_mode) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) > + tp_assign(uid, i_uid_read(inode)) > + tp_assign(gid, i_gid_read(inode)) > +#else > tp_assign(uid, inode->i_uid) > tp_assign(gid, inode->i_gid) > +#endif > tp_assign(blocks, inode->i_blocks) > ), > > diff --git a/instrumentation/events/lttng-module/jbd.h b/instrumentation/events/lttng-module/jbd.h > index b6bd64a..570bdac 100644 > --- a/instrumentation/events/lttng-module/jbd.h > +++ b/instrumentation/events/lttng-module/jbd.h > @@ -6,6 +6,7 @@ > > #include > #include > +#include > > TRACE_EVENT(jbd_checkpoint, > > @@ -217,6 +218,26 @@ TRACE_EVENT(jbd_cleanup_journal_tail, > __entry->block_nr, __entry->freed) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) > +TRACE_EVENT(journal_write_superblock, > + TP_PROTO(journal_t *journal, int write_op), > + > + TP_ARGS(journal, write_op), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, write_op ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(write_op, write_op) > + ), > + > + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), > + MINOR(__entry->dev), __entry->write_op) > +) > +#else > TRACE_EVENT(jbd_update_superblock_end, > TP_PROTO(journal_t *journal, int wait), > > @@ -236,6 +257,7 @@ TRACE_EVENT(jbd_update_superblock_end, > MAJOR(__entry->dev), MINOR(__entry->dev), > __entry->wait) > ) > +#endif > > #endif /* _TRACE_JBD_H */ > > diff --git a/instrumentation/events/lttng-module/jbd2.h b/instrumentation/events/lttng-module/jbd2.h > index c7992c0..cc6b933 100644 > --- a/instrumentation/events/lttng-module/jbd2.h > +++ b/instrumentation/events/lttng-module/jbd2.h > @@ -6,6 +6,7 @@ > > #include > #include > +#include > > #ifndef _TRACE_JBD2_DEF > #define _TRACE_JBD2_DEF > @@ -84,6 +85,15 @@ DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, > TP_ARGS(journal, commit_transaction) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > +DEFINE_EVENT(jbd2_commit, jbd2_drop_transaction, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +) > +#endif > + > TRACE_EVENT(jbd2_end_commit, > TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > > @@ -203,7 +213,11 @@ TRACE_EVENT(jbd2_checkpoint_stats, > __entry->forced_to_close, __entry->written, __entry->dropped) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > +TRACE_EVENT(jbd2_update_log_tail, > +#else > TRACE_EVENT(jbd2_cleanup_journal_tail, > +#endif > > TP_PROTO(journal_t *journal, tid_t first_tid, > unsigned long block_nr, unsigned long freed), > @@ -232,6 +246,28 @@ TRACE_EVENT(jbd2_cleanup_journal_tail, > __entry->block_nr, __entry->freed) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > +TRACE_EVENT(jbd2_write_superblock, > + > + TP_PROTO(journal_t *journal, int write_op), > + > + TP_ARGS(journal, write_op), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, write_op ) > + ), > + > + TP_fast_assign( > + tp_assign(dev, journal->j_fs_dev->bd_dev) > + tp_assign(write_op, write_op) > + ), > + > + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), > + MINOR(__entry->dev), __entry->write_op) > +) > +#endif > + > #endif /* _TRACE_JBD2_H */ > > /* This part must be outside protection */ > diff --git a/instrumentation/events/lttng-module/kmem.h b/instrumentation/events/lttng-module/kmem.h > index dab8989..11938d1 100644 > --- a/instrumentation/events/lttng-module/kmem.h > +++ b/instrumentation/events/lttng-module/kmem.h > @@ -4,6 +4,11 @@ > #if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) > #define _TRACE_KMEM_H > > +#include > +#include > +#include > +#include > + > DECLARE_EVENT_CLASS(kmem_alloc, > > TP_PROTO(unsigned long call_site, > @@ -143,7 +148,11 @@ DEFINE_EVENT(kmem_free, kmem_cache_free, > TP_ARGS(call_site, ptr) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > +TRACE_EVENT(mm_page_free, > +#else > TRACE_EVENT(mm_page_free_direct, > +#endif > > TP_PROTO(struct page *page, unsigned int order), > > @@ -165,7 +174,11 @@ TRACE_EVENT(mm_page_free_direct, > __entry->order) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > +TRACE_EVENT(mm_page_free_batched, > +#else > TRACE_EVENT(mm_pagevec_free, > +#endif > > TP_PROTO(struct page *page, int cold), > > @@ -210,7 +223,7 @@ TRACE_EVENT(mm_page_alloc, > > TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > __entry->page, > - page_to_pfn(__entry->page), > + __entry->page ? page_to_pfn(__entry->page) : 0, > __entry->order, > __entry->migratetype, > show_gfp_flags(__entry->gfp_flags)) > @@ -236,7 +249,7 @@ DECLARE_EVENT_CLASS(mm_page, > > TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > __entry->page, > - page_to_pfn(__entry->page), > + __entry->page ? page_to_pfn(__entry->page) : 0, > __entry->order, > __entry->migratetype, > __entry->order == 0) > diff --git a/instrumentation/events/lttng-module/power.h b/instrumentation/events/lttng-module/power.h > index f2e3f54..6023593 100644 > --- a/instrumentation/events/lttng-module/power.h > +++ b/instrumentation/events/lttng-module/power.h > @@ -6,6 +6,7 @@ > > #include > #include > +#include > > DECLARE_EVENT_CLASS(cpu, > > @@ -65,7 +66,42 @@ TRACE_EVENT(machine_suspend, > TP_printk("state=%lu", (unsigned long)__entry->state) > ) > > -/* This code will be removed after deprecation time exceeded (2.6.41) */ > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) > +DECLARE_EVENT_CLASS(wakeup_source, > + > + TP_PROTO(const char *name, unsigned int state), > + > + TP_ARGS(name, state), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + ), > + > + TP_fast_assign( > + tp_strcpy(name, name) > + tp_assign(state, state) > + ), > + > + TP_printk("%s state=0x%lx", __get_str(name), > + (unsigned long)__entry->state) > +) > + > +DEFINE_EVENT(wakeup_source, wakeup_source_activate, > + > + TP_PROTO(const char *name, unsigned int state), > + > + TP_ARGS(name, state) > +) > + > +DEFINE_EVENT(wakeup_source, wakeup_source_deactivate, > + > + TP_PROTO(const char *name, unsigned int state), > + > + TP_ARGS(name, state) > +) > +#endif > + > #ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED > > /* > @@ -151,6 +187,10 @@ enum { > events get removed */ > static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; > static inline void trace_power_end(u64 cpuid) {}; > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > +static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {}; > +static inline void trace_power_end_rcuidle(u64 cpuid) {}; > +#endif > static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; > #endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > > diff --git a/instrumentation/events/lttng-module/sched.h b/instrumentation/events/lttng-module/sched.h > index 005f3d1..b84aef7 100644 > --- a/instrumentation/events/lttng-module/sched.h > +++ b/instrumentation/events/lttng-module/sched.h > @@ -6,6 +6,8 @@ > > #include > #include > +#include > +#include > > #ifndef _TRACE_SCHED_DEF_ > #define _TRACE_SCHED_DEF_ > @@ -19,8 +21,12 @@ static inline long __trace_sched_switch_state(struct task_struct *p) > * For all intents and purposes a preempted task is a running task. > */ > if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) > + state = TASK_RUNNING | TASK_STATE_MAX; > +#else > state = TASK_RUNNING; > #endif > +#endif > > return state; > } > @@ -98,6 +104,11 @@ DECLARE_EVENT_CLASS(sched_wakeup_template, > tp_assign(prio, p->prio) > tp_assign(success, success) > tp_assign(target_cpu, task_cpu(p)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) > + ) > + TP_perf_assign( > + __perf_task(p) > +#endif > ), > > TP_printk("comm=%s tid=%d prio=%d success=%d target_cpu=%03d", > @@ -170,6 +181,17 @@ TRACE_EVENT(sched_switch, > tp_assign(next_prio, next->prio - MAX_RT_PRIO) > ), > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) > + TP_printk("prev_comm=%s prev_tid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_tid=%d next_prio=%d", > + __entry->prev_comm, __entry->prev_tid, __entry->prev_prio, > + __entry->prev_state & (TASK_STATE_MAX-1) ? > + __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|", > + { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, > + { 16, "Z" }, { 32, "X" }, { 64, "x" }, > + { 128, "W" }) : "R", > + __entry->prev_state & TASK_STATE_MAX ? "+" : "", > + __entry->next_comm, __entry->next_tid, __entry->next_prio) > +#else > TP_printk("prev_comm=%s prev_tid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_tid=%d next_prio=%d", > __entry->prev_comm, __entry->prev_tid, __entry->prev_prio, > __entry->prev_state ? > @@ -178,6 +200,7 @@ TRACE_EVENT(sched_switch, > { 16, "Z" }, { 32, "X" }, { 64, "x" }, > { 128, "W" }) : "R", > __entry->next_comm, __entry->next_tid, __entry->next_prio) > +#endif > ) > > /* > @@ -396,6 +419,15 @@ DEFINE_EVENT(sched_stat_template, sched_stat_iowait, > TP_PROTO(struct task_struct *tsk, u64 delay), > TP_ARGS(tsk, delay)) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > +/* > + * Tracepoint for accounting blocked time (time the task is in uninterruptible). > + */ > +DEFINE_EVENT(sched_stat_template, sched_stat_blocked, > + TP_PROTO(struct task_struct *tsk, u64 delay), > + TP_ARGS(tsk, delay)) > +#endif > + > /* > * Tracepoint for accounting runtime (time the task is executing > * on a CPU). > @@ -421,6 +453,9 @@ TRACE_EVENT(sched_stat_runtime, > ) > TP_perf_assign( > __perf_count(runtime) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) > + __perf_task(tsk) > +#endif > ), > > TP_printk("comm=%s tid=%d runtime=%Lu [ns] vruntime=%Lu [ns]", > @@ -429,6 +464,7 @@ TRACE_EVENT(sched_stat_runtime, > (unsigned long long)__entry->vruntime) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) > /* > * Tracepoint for showing priority inheritance modifying a tasks > * priority. > @@ -457,6 +493,7 @@ TRACE_EVENT(sched_pi_setprio, > __entry->comm, __entry->tid, > __entry->oldprio, __entry->newprio) > ) > +#endif > > #endif /* _TRACE_SCHED_H */ > > diff --git a/instrumentation/events/lttng-module/scsi.h b/instrumentation/events/lttng-module/scsi.h > index 18d2b02..15f0c70 100644 > --- a/instrumentation/events/lttng-module/scsi.h > +++ b/instrumentation/events/lttng-module/scsi.h > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > > #ifndef _TRACE_SCSI_DEF > #define _TRACE_SCSI_DEF > @@ -187,6 +188,7 @@ > scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ > scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > #define scsi_prot_op_name(result) { result, #result } > #define show_prot_op_name(val) \ > __print_symbolic(val, \ > @@ -197,6 +199,7 @@ > scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ > scsi_prot_op_name(SCSI_PROT_READ_PASS), \ > scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) > +#endif > > const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); > #define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) > @@ -217,7 +220,9 @@ TRACE_EVENT(scsi_dispatch_cmd_start, > __field( unsigned int, cmd_len ) > __field( unsigned int, data_sglen ) > __field( unsigned int, prot_sglen ) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > __field( unsigned char, prot_op ) > +#endif > __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > ), > > @@ -230,15 +235,24 @@ TRACE_EVENT(scsi_dispatch_cmd_start, > tp_assign(cmd_len, cmd->cmd_len) > tp_assign(data_sglen, scsi_sg_count(cmd)) > tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > tp_assign(prot_op, scsi_get_prot_op(cmd)) > +#endif > tp_memcpy_dyn(cmnd, cmd->cmnd) > ), > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > " prot_op=%s cmnd=(%s %s raw=%s)", > +#else > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " cmnd=(%s %s raw=%s)", > +#endif > __entry->host_no, __entry->channel, __entry->id, > __entry->lun, __entry->data_sglen, __entry->prot_sglen, > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > show_prot_op_name(__entry->prot_op), > +#endif > show_opcode_name(__entry->opcode), > __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) > @@ -260,7 +274,9 @@ TRACE_EVENT(scsi_dispatch_cmd_error, > __field( unsigned int, cmd_len ) > __field( unsigned int, data_sglen ) > __field( unsigned int, prot_sglen ) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > __field( unsigned char, prot_op ) > +#endif > __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > ), > > @@ -274,15 +290,24 @@ TRACE_EVENT(scsi_dispatch_cmd_error, > tp_assign(cmd_len, cmd->cmd_len) > tp_assign(data_sglen, scsi_sg_count(cmd)) > tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > tp_assign(prot_op, scsi_get_prot_op(cmd)) > +#endif > tp_memcpy_dyn(cmnd, cmd->cmnd) > ), > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", > +#else > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ > + " cmnd=(%s %s raw=%s) rtn=%d", > +#endif > __entry->host_no, __entry->channel, __entry->id, > __entry->lun, __entry->data_sglen, __entry->prot_sglen, > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > show_prot_op_name(__entry->prot_op), > +#endif > show_opcode_name(__entry->opcode), > __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > @@ -305,7 +330,9 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > __field( unsigned int, cmd_len ) > __field( unsigned int, data_sglen ) > __field( unsigned int, prot_sglen ) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > __field( unsigned char, prot_op ) > +#endif > __dynamic_array_hex(unsigned char, cmnd, cmd->cmd_len) > ), > > @@ -319,16 +346,26 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, > tp_assign(cmd_len, cmd->cmd_len) > tp_assign(data_sglen, scsi_sg_count(cmd)) > tp_assign(prot_sglen, scsi_prot_sg_count(cmd)) > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > tp_assign(prot_op, scsi_get_prot_op(cmd)) > +#endif > tp_memcpy_dyn(cmnd, cmd->cmnd) > ), > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ > "%s host=%s message=%s status=%s)", > +#else > + TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ > + "prot_sgl=%u cmnd=(%s %s raw=%s) result=(driver=%s host=%s " \ > + "message=%s status=%s)", > +#endif > __entry->host_no, __entry->channel, __entry->id, > __entry->lun, __entry->data_sglen, __entry->prot_sglen, > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) > show_prot_op_name(__entry->prot_op), > +#endif > show_opcode_name(__entry->opcode), > __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), > __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), > diff --git a/instrumentation/events/lttng-module/signal.h b/instrumentation/events/lttng-module/signal.h > index 945747f..a1c904b 100644 > --- a/instrumentation/events/lttng-module/signal.h > +++ b/instrumentation/events/lttng-module/signal.h > @@ -135,6 +135,7 @@ TRACE_EVENT(signal_deliver, > __entry->sa_handler, __entry->sa_flags) > ) > > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) > DECLARE_EVENT_CLASS(signal_queue_overflow, > > TP_PROTO(int sig, int group, struct siginfo *info), > @@ -193,6 +194,7 @@ DEFINE_EVENT(signal_queue_overflow, signal_lose_info, > > TP_ARGS(sig, group, info) > ) > +#endif > > #endif /* _TRACE_SIGNAL_H */ > > diff --git a/instrumentation/events/lttng-module/vmscan.h b/instrumentation/events/lttng-module/vmscan.h > index d6ab952..3bb8696 100644 > --- a/instrumentation/events/lttng-module/vmscan.h > +++ b/instrumentation/events/lttng-module/vmscan.h > @@ -4,6 +4,65 @@ > #if !defined(_TRACE_VMSCAN_H) || defined(TRACE_HEADER_MULTI_READ) > #define _TRACE_VMSCAN_H > > +#include > +#include > +#include > +#include > +#include > +#include > + > +#ifndef _TRACE_VMSCAN_DEF > +#define _TRACE_VMSCAN_DEF > +#define RECLAIM_WB_ANON 0x0001u > +#define RECLAIM_WB_FILE 0x0002u > +#define RECLAIM_WB_MIXED 0x0010u > +#define RECLAIM_WB_SYNC 0x0004u /* Unused, all reclaim async */ > +#define RECLAIM_WB_ASYNC 0x0008u > + > +#define show_reclaim_flags(flags) \ > + (flags) ? __print_flags(flags, "|", \ > + {RECLAIM_WB_ANON, "RECLAIM_WB_ANON"}, \ > + {RECLAIM_WB_FILE, "RECLAIM_WB_FILE"}, \ > + {RECLAIM_WB_MIXED, "RECLAIM_WB_MIXED"}, \ > + {RECLAIM_WB_SYNC, "RECLAIM_WB_SYNC"}, \ > + {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ > + ) : "RECLAIM_WB_NONE" > + > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + > +#define trace_reclaim_flags(page, sync) ( \ > + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + ) > + > +#define trace_shrink_flags(file, sync) ( \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ > + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ > + (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + ) > + > +#else > + > +#define trace_reclaim_flags(page) ( \ > + (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > + (RECLAIM_WB_ASYNC) \ > + ) > + > +#define trace_shrink_flags(file) \ > + ( \ > + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > + (RECLAIM_WB_ASYNC) \ > + ) > + > +#endif > + > +#if ((LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ > + LTTNG_KERNEL_RANGE(3,1,0, 3,2,0)) > +typedef int isolate_mode_t; > +#endif > + > +#endif > + > TRACE_EVENT(mm_vmscan_kswapd_sleep, > > TP_PROTO(int nid), > @@ -147,6 +206,7 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_re > TP_ARGS(nr_reclaimed) > ) > > +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) > TRACE_EVENT(mm_shrink_slab_start, > TP_PROTO(struct shrinker *shr, struct shrink_control *sc, > long nr_objects_to_shrink, unsigned long pgs_scanned, > @@ -224,6 +284,7 @@ TRACE_EVENT(mm_shrink_slab_end, > __entry->total_scan, > __entry->retval) > ) > +#endif > > DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > > @@ -231,30 +292,41 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > unsigned long nr_requested, > unsigned long nr_scanned, > unsigned long nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > unsigned long nr_lumpy_taken, > unsigned long nr_lumpy_dirty, > unsigned long nr_lumpy_failed, > +#endif > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > - isolate_mode_t isolate_mode), > + isolate_mode_t isolate_mode > #else > isolate_mode_t isolate_mode, > - int file), > + int file > #endif > + ), > > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, > +#endif > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), > + isolate_mode > #else > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file), > + isolate_mode, file > #endif > + ), > + > > TP_STRUCT__entry( > __field(int, order) > __field(unsigned long, nr_requested) > __field(unsigned long, nr_scanned) > __field(unsigned long, nr_taken) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > __field(unsigned long, nr_lumpy_taken) > __field(unsigned long, nr_lumpy_dirty) > __field(unsigned long, nr_lumpy_failed) > +#endif > __field(isolate_mode_t, isolate_mode) > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > __field(int, file) > @@ -266,9 +338,11 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > tp_assign(nr_requested, nr_requested) > tp_assign(nr_scanned, nr_scanned) > tp_assign(nr_taken, nr_taken) > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > tp_assign(nr_lumpy_taken, nr_lumpy_taken) > tp_assign(nr_lumpy_dirty, nr_lumpy_dirty) > tp_assign(nr_lumpy_failed, nr_lumpy_failed) > +#endif > tp_assign(isolate_mode, isolate_mode) > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) > tp_assign(file, file) > @@ -277,9 +351,6 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", > -#else > - TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", > -#endif > __entry->isolate_mode, > __entry->order, > __entry->nr_requested, > @@ -287,11 +358,26 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > __entry->nr_taken, > __entry->nr_lumpy_taken, > __entry->nr_lumpy_dirty, > -#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > __entry->nr_lumpy_failed) > -#else > +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu file=%d", > + __entry->isolate_mode, > + __entry->order, > + __entry->nr_requested, > + __entry->nr_scanned, > + __entry->nr_taken, > + __entry->nr_lumpy_taken, > + __entry->nr_lumpy_dirty, > __entry->nr_lumpy_failed, > __entry->file) > +#else > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d", > + __entry->isolate_mode, > + __entry->order, > + __entry->nr_requested, > + __entry->nr_scanned, > + __entry->nr_taken, > + __entry->file) > #endif > ) > > @@ -307,19 +393,23 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > unsigned long nr_lumpy_failed, > #endif > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > - isolate_mode_t isolate_mode), > + isolate_mode_t isolate_mode > #else > isolate_mode_t isolate_mode, > - int file), > + int file > #endif > + ), > > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, > +#endif > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) > + isolate_mode > #else > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > + isolate_mode, file > #endif > + ) > > ) > > @@ -335,19 +425,23 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, > unsigned long nr_lumpy_failed, > #endif > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > - isolate_mode_t isolate_mode), > + isolate_mode_t isolate_mode > #else > isolate_mode_t isolate_mode, > - int file), > + int file > #endif > + ), > > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, > +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > + nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, > +#endif > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > -#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode, file) > + isolate_mode > #else > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > + isolate_mode, file > #endif > + ) > > ) > > @@ -408,7 +502,6 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > ) > > #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) > - > TRACE_EVENT(replace_swap_token, > TP_PROTO(struct mm_struct *old_mm, > struct mm_struct *new_mm), > @@ -490,7 +583,6 @@ TRACE_EVENT_CONDITION(update_swap_token_priority, > __entry->mm, __entry->old_prio, __entry->new_prio, > __entry->swap_token_mm, __entry->swap_token_prio) > ) > - > #endif > > #endif /* _TRACE_VMSCAN_H */ > diff --git a/instrumentation/events/mainline/asoc.h b/instrumentation/events/mainline/asoc.h > index ab26f8a..5fc2dcd 100644 > --- a/instrumentation/events/mainline/asoc.h > +++ b/instrumentation/events/mainline/asoc.h > @@ -7,6 +7,8 @@ > #include > #include > > +#define DAPM_DIRECT "(direct)" > + > struct snd_soc_jack; > struct snd_soc_codec; > struct snd_soc_platform; > @@ -241,6 +243,84 @@ TRACE_EVENT(snd_soc_dapm_walk_done, > (int)__entry->path_checks, (int)__entry->neighbour_checks) > ); > > +TRACE_EVENT(snd_soc_dapm_output_path, > + > + TP_PROTO(struct snd_soc_dapm_widget *widget, > + struct snd_soc_dapm_path *path), > + > + TP_ARGS(widget, path), > + > + TP_STRUCT__entry( > + __string( wname, widget->name ) > + __string( pname, path->name ? path->name : DAPM_DIRECT) > + __string( psname, path->sink->name ) > + __field( int, path_sink ) > + __field( int, path_connect ) > + ), > + > + TP_fast_assign( > + __assign_str(wname, widget->name); > + __assign_str(pname, path->name ? path->name : DAPM_DIRECT); > + __assign_str(psname, path->sink->name); > + __entry->path_connect = path->connect; > + __entry->path_sink = (long)path->sink; > + ), > + > + TP_printk("%c%s -> %s -> %s\n", > + (int) __entry->path_sink && > + (int) __entry->path_connect ? '*' : ' ', > + __get_str(wname), __get_str(pname), __get_str(psname)) > +); > + > +TRACE_EVENT(snd_soc_dapm_input_path, > + > + TP_PROTO(struct snd_soc_dapm_widget *widget, > + struct snd_soc_dapm_path *path), > + > + TP_ARGS(widget, path), > + > + TP_STRUCT__entry( > + __string( wname, widget->name ) > + __string( pname, path->name ? path->name : DAPM_DIRECT) > + __string( psname, path->source->name ) > + __field( int, path_source ) > + __field( int, path_connect ) > + ), > + > + TP_fast_assign( > + __assign_str(wname, widget->name); > + __assign_str(pname, path->name ? path->name : DAPM_DIRECT); > + __assign_str(psname, path->source->name); > + __entry->path_connect = path->connect; > + __entry->path_source = (long)path->source; > + ), > + > + TP_printk("%c%s <- %s <- %s\n", > + (int) __entry->path_source && > + (int) __entry->path_connect ? '*' : ' ', > + __get_str(wname), __get_str(pname), __get_str(psname)) > +); > + > +TRACE_EVENT(snd_soc_dapm_connected, > + > + TP_PROTO(int paths, int stream), > + > + TP_ARGS(paths, stream), > + > + TP_STRUCT__entry( > + __field( int, paths ) > + __field( int, stream ) > + ), > + > + TP_fast_assign( > + __entry->paths = paths; > + __entry->stream = stream; > + ), > + > + TP_printk("%s: found %d paths\n", > + __entry->stream ? "capture" : "playback", __entry->paths) > +); > + > TRACE_EVENT(snd_soc_jack_irq, > > TP_PROTO(const char *name), > diff --git a/instrumentation/events/mainline/block.h b/instrumentation/events/mainline/block.h > index bf36654..05c5e61 100644 > --- a/instrumentation/events/mainline/block.h > +++ b/instrumentation/events/mainline/block.h > @@ -8,6 +8,8 @@ > #include > #include > > +#define RWBS_LEN 8 > + > DECLARE_EVENT_CLASS(block_rq_with_error, > > TP_PROTO(struct request_queue *q, struct request *rq), > @@ -19,7 +21,7 @@ DECLARE_EVENT_CLASS(block_rq_with_error, > __field( sector_t, sector ) > __field( unsigned int, nr_sector ) > __field( int, errors ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN ) > __dynamic_array( char, cmd, blk_cmd_buf_len(rq) ) > ), > > @@ -104,7 +106,7 @@ DECLARE_EVENT_CLASS(block_rq, > __field( sector_t, sector ) > __field( unsigned int, nr_sector ) > __field( unsigned int, bytes ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN ) > __array( char, comm, TASK_COMM_LEN ) > __dynamic_array( char, cmd, blk_cmd_buf_len(rq) ) > ), > @@ -183,7 +185,7 @@ TRACE_EVENT(block_bio_bounce, > __field( dev_t, dev ) > __field( sector_t, sector ) > __field( unsigned int, nr_sector ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN ) > __array( char, comm, TASK_COMM_LEN ) > ), > > @@ -222,7 +224,7 @@ TRACE_EVENT(block_bio_complete, > __field( sector_t, sector ) > __field( unsigned, nr_sector ) > __field( int, error ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN) > ), > > TP_fast_assign( > @@ -249,7 +251,7 @@ DECLARE_EVENT_CLASS(block_bio, > __field( dev_t, dev ) > __field( sector_t, sector ) > __field( unsigned int, nr_sector ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN ) > __array( char, comm, TASK_COMM_LEN ) > ), > > @@ -321,7 +323,7 @@ DECLARE_EVENT_CLASS(block_get_rq, > __field( dev_t, dev ) > __field( sector_t, sector ) > __field( unsigned int, nr_sector ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN ) > __array( char, comm, TASK_COMM_LEN ) > ), > > @@ -456,7 +458,7 @@ TRACE_EVENT(block_split, > __field( dev_t, dev ) > __field( sector_t, sector ) > __field( sector_t, new_sector ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN ) > __array( char, comm, TASK_COMM_LEN ) > ), > > @@ -498,7 +500,7 @@ TRACE_EVENT(block_bio_remap, > __field( unsigned int, nr_sector ) > __field( dev_t, old_dev ) > __field( sector_t, old_sector ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN) > ), > > TP_fast_assign( > @@ -542,7 +544,7 @@ TRACE_EVENT(block_rq_remap, > __field( unsigned int, nr_sector ) > __field( dev_t, old_dev ) > __field( sector_t, old_sector ) > - __array( char, rwbs, 6 ) > + __array( char, rwbs, RWBS_LEN) > ), > > TP_fast_assign( > diff --git a/instrumentation/events/mainline/ext3.h b/instrumentation/events/mainline/ext3.h > index 7b53c05..15d11a3 100644 > --- a/instrumentation/events/mainline/ext3.h > +++ b/instrumentation/events/mainline/ext3.h > @@ -24,8 +24,8 @@ TRACE_EVENT(ext3_free_inode, > __entry->dev = inode->i_sb->s_dev; > __entry->ino = inode->i_ino; > __entry->mode = inode->i_mode; > - __entry->uid = inode->i_uid; > - __entry->gid = inode->i_gid; > + __entry->uid = i_uid_read(inode); > + __entry->gid = i_gid_read(inode); > __entry->blocks = inode->i_blocks; > ), > > diff --git a/instrumentation/events/mainline/fs_ext3.h b/instrumentation/events/mainline/fs_ext3.h > deleted file mode 100644 > index 76353e4..0000000 > --- a/instrumentation/events/mainline/fs_ext3.h > +++ /dev/null > @@ -1,1323 +0,0 @@ > -/* > - * Written by Stephen C. Tweedie , 1999 > - * > - * Copyright 1998--1999 Red Hat corp --- All Rights Reserved > - * > - * This file is part of the Linux kernel and is made available under > - * the terms of the GNU General Public License, version 2, or at your > - * option, any later version, incorporated herein by reference. > - * > - * Copyright (C) 1992, 1993, 1994, 1995 > - * Remy Card (card at masi.ibp.fr) > - * Laboratoire MASI - Institut Blaise Pascal > - * Universite Pierre et Marie Curie (Paris VI) > - * > - * from > - * > - * linux/include/linux/minix_fs.h > - * > - * Copyright (C) 1991, 1992 Linus Torvalds > - */ > - > -#include > -#include > -#include > -#include > -#include > - > -/* > - * The second extended filesystem constants/structures > - */ > - > -/* > - * Define EXT3FS_DEBUG to produce debug messages > - */ > -#undef EXT3FS_DEBUG > - > -/* > - * Define EXT3_RESERVATION to reserve data blocks for expanding files > - */ > -#define EXT3_DEFAULT_RESERVE_BLOCKS 8 > -/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ > -#define EXT3_MAX_RESERVE_BLOCKS 1027 > -#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0 > - > -/* > - * Debug code > - */ > -#ifdef EXT3FS_DEBUG > -#define ext3_debug(f, a...) \ > - do { \ > - printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ > - __FILE__, __LINE__, __func__); \ > - printk (KERN_DEBUG f, ## a); \ > - } while (0) > -#else > -#define ext3_debug(f, a...) do {} while (0) > -#endif > - > -/* > - * Special inodes numbers > - */ > -#define EXT3_BAD_INO 1 /* Bad blocks inode */ > -#define EXT3_ROOT_INO 2 /* Root inode */ > -#define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ > -#define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ > -#define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ > -#define EXT3_JOURNAL_INO 8 /* Journal inode */ > - > -/* First non-reserved inode for old ext3 filesystems */ > -#define EXT3_GOOD_OLD_FIRST_INO 11 > - > -/* > - * Maximal count of links to a file > - */ > -#define EXT3_LINK_MAX 32000 > - > -/* > - * Macro-instructions used to manage several block sizes > - */ > -#define EXT3_MIN_BLOCK_SIZE 1024 > -#define EXT3_MAX_BLOCK_SIZE 65536 > -#define EXT3_MIN_BLOCK_LOG_SIZE 10 > -#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) > -#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) > -#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) > -#define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) > -#define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) > -#define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) > - > -/* > - * Macro-instructions used to manage fragments > - */ > -#define EXT3_MIN_FRAG_SIZE 1024 > -#define EXT3_MAX_FRAG_SIZE 4096 > -#define EXT3_MIN_FRAG_LOG_SIZE 10 > -#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) > -#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) > - > -/* > - * Structure of a blocks group descriptor > - */ > -struct ext3_group_desc > -{ > - __le32 bg_block_bitmap; /* Blocks bitmap block */ > - __le32 bg_inode_bitmap; /* Inodes bitmap block */ > - __le32 bg_inode_table; /* Inodes table block */ > - __le16 bg_free_blocks_count; /* Free blocks count */ > - __le16 bg_free_inodes_count; /* Free inodes count */ > - __le16 bg_used_dirs_count; /* Directories count */ > - __u16 bg_pad; > - __le32 bg_reserved[3]; > -}; > - > -/* > - * Macro-instructions used to manage group descriptors > - */ > -#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) > -#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) > -#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) > -#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) > - > -/* > - * Constants relative to the data blocks > - */ > -#define EXT3_NDIR_BLOCKS 12 > -#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS > -#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1) > -#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1) > -#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1) > - > -/* > - * Inode flags > - */ > -#define EXT3_SECRM_FL 0x00000001 /* Secure deletion */ > -#define EXT3_UNRM_FL 0x00000002 /* Undelete */ > -#define EXT3_COMPR_FL 0x00000004 /* Compress file */ > -#define EXT3_SYNC_FL 0x00000008 /* Synchronous updates */ > -#define EXT3_IMMUTABLE_FL 0x00000010 /* Immutable file */ > -#define EXT3_APPEND_FL 0x00000020 /* writes to file may only append */ > -#define EXT3_NODUMP_FL 0x00000040 /* do not dump file */ > -#define EXT3_NOATIME_FL 0x00000080 /* do not update atime */ > -/* Reserved for compression usage... */ > -#define EXT3_DIRTY_FL 0x00000100 > -#define EXT3_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */ > -#define EXT3_NOCOMPR_FL 0x00000400 /* Don't compress */ > -#define EXT3_ECOMPR_FL 0x00000800 /* Compression error */ > -/* End compression flags --- maybe not all used */ > -#define EXT3_INDEX_FL 0x00001000 /* hash-indexed directory */ > -#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ > -#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ > -#define EXT3_NOTAIL_FL 0x00008000 /* file tail should not be merged */ > -#define EXT3_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ > -#define EXT3_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ > -#define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ > - > -#define EXT3_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ > -#define EXT3_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */ > - > -/* Flags that should be inherited by new inodes from their parent. */ > -#define EXT3_FL_INHERITED (EXT3_SECRM_FL | EXT3_UNRM_FL | EXT3_COMPR_FL |\ > - EXT3_SYNC_FL | EXT3_NODUMP_FL |\ > - EXT3_NOATIME_FL | EXT3_COMPRBLK_FL |\ > - EXT3_NOCOMPR_FL | EXT3_JOURNAL_DATA_FL |\ > - EXT3_NOTAIL_FL | EXT3_DIRSYNC_FL) > - > -/* Flags that are appropriate for regular files (all but dir-specific ones). */ > -#define EXT3_REG_FLMASK (~(EXT3_DIRSYNC_FL | EXT3_TOPDIR_FL)) > - > -/* Flags that are appropriate for non-directories/regular files. */ > -#define EXT3_OTHER_FLMASK (EXT3_NODUMP_FL | EXT3_NOATIME_FL) > - > -/* Mask out flags that are inappropriate for the given type of inode. */ > -static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) > -{ > - if (S_ISDIR(mode)) > - return flags; > - else if (S_ISREG(mode)) > - return flags & EXT3_REG_FLMASK; > - else > - return flags & EXT3_OTHER_FLMASK; > -} > - > -/* Used to pass group descriptor data when online resize is done */ > -struct ext3_new_group_input { > - __u32 group; /* Group number for this data */ > - __u32 block_bitmap; /* Absolute block number of block bitmap */ > - __u32 inode_bitmap; /* Absolute block number of inode bitmap */ > - __u32 inode_table; /* Absolute block number of inode table start */ > - __u32 blocks_count; /* Total number of blocks in this group */ > - __u16 reserved_blocks; /* Number of reserved blocks in this group */ > - __u16 unused; > -}; > - > -/* The struct ext3_new_group_input in kernel space, with free_blocks_count */ > -struct ext3_new_group_data { > - __u32 group; > - __u32 block_bitmap; > - __u32 inode_bitmap; > - __u32 inode_table; > - __u32 blocks_count; > - __u16 reserved_blocks; > - __u16 unused; > - __u32 free_blocks_count; > -}; > - > - > -/* > - * ioctl commands > - */ > -#define EXT3_IOC_GETFLAGS FS_IOC_GETFLAGS > -#define EXT3_IOC_SETFLAGS FS_IOC_SETFLAGS > -#define EXT3_IOC_GETVERSION _IOR('f', 3, long) > -#define EXT3_IOC_SETVERSION _IOW('f', 4, long) > -#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) > -#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input) > -#define EXT3_IOC_GETVERSION_OLD FS_IOC_GETVERSION > -#define EXT3_IOC_SETVERSION_OLD FS_IOC_SETVERSION > -#ifdef CONFIG_JBD_DEBUG > -#define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) > -#endif > -#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long) > -#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long) > - > -/* > - * ioctl commands in 32 bit emulation > - */ > -#define EXT3_IOC32_GETFLAGS FS_IOC32_GETFLAGS > -#define EXT3_IOC32_SETFLAGS FS_IOC32_SETFLAGS > -#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) > -#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) > -#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) > -#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) > -#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) > -#ifdef CONFIG_JBD_DEBUG > -#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) > -#endif > -#define EXT3_IOC32_GETVERSION_OLD FS_IOC32_GETVERSION > -#define EXT3_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION > - > - > -/* > - * Mount options > - */ > -struct ext3_mount_options { > - unsigned long s_mount_opt; > - uid_t s_resuid; > - gid_t s_resgid; > - unsigned long s_commit_interval; > -#ifdef CONFIG_QUOTA > - int s_jquota_fmt; > - char *s_qf_names[MAXQUOTAS]; > -#endif > -}; > - > -/* > - * Structure of an inode on the disk > - */ > -struct ext3_inode { > - __le16 i_mode; /* File mode */ > - __le16 i_uid; /* Low 16 bits of Owner Uid */ > - __le32 i_size; /* Size in bytes */ > - __le32 i_atime; /* Access time */ > - __le32 i_ctime; /* Creation time */ > - __le32 i_mtime; /* Modification time */ > - __le32 i_dtime; /* Deletion Time */ > - __le16 i_gid; /* Low 16 bits of Group Id */ > - __le16 i_links_count; /* Links count */ > - __le32 i_blocks; /* Blocks count */ > - __le32 i_flags; /* File flags */ > - union { > - struct { > - __u32 l_i_reserved1; > - } linux1; > - struct { > - __u32 h_i_translator; > - } hurd1; > - struct { > - __u32 m_i_reserved1; > - } masix1; > - } osd1; /* OS dependent 1 */ > - __le32 i_block[EXT3_N_BLOCKS];/* Pointers to blocks */ > - __le32 i_generation; /* File version (for NFS) */ > - __le32 i_file_acl; /* File ACL */ > - __le32 i_dir_acl; /* Directory ACL */ > - __le32 i_faddr; /* Fragment address */ > - union { > - struct { > - __u8 l_i_frag; /* Fragment number */ > - __u8 l_i_fsize; /* Fragment size */ > - __u16 i_pad1; > - __le16 l_i_uid_high; /* these 2 fields */ > - __le16 l_i_gid_high; /* were reserved2[0] */ > - __u32 l_i_reserved2; > - } linux2; > - struct { > - __u8 h_i_frag; /* Fragment number */ > - __u8 h_i_fsize; /* Fragment size */ > - __u16 h_i_mode_high; > - __u16 h_i_uid_high; > - __u16 h_i_gid_high; > - __u32 h_i_author; > - } hurd2; > - struct { > - __u8 m_i_frag; /* Fragment number */ > - __u8 m_i_fsize; /* Fragment size */ > - __u16 m_pad1; > - __u32 m_i_reserved2[2]; > - } masix2; > - } osd2; /* OS dependent 2 */ > - __le16 i_extra_isize; > - __le16 i_pad1; > -}; > - > -#define i_size_high i_dir_acl > - > -#define i_reserved1 osd1.linux1.l_i_reserved1 > -#define i_frag osd2.linux2.l_i_frag > -#define i_fsize osd2.linux2.l_i_fsize > -#define i_uid_low i_uid > -#define i_gid_low i_gid > -#define i_uid_high osd2.linux2.l_i_uid_high > -#define i_gid_high osd2.linux2.l_i_gid_high > -#define i_reserved2 osd2.linux2.l_i_reserved2 > - > -/* > - * File system states > - */ > -#define EXT3_VALID_FS 0x0001 /* Unmounted cleanly */ > -#define EXT3_ERROR_FS 0x0002 /* Errors detected */ > -#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */ > - > -/* > - * Misc. filesystem flags > - */ > -#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ > -#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ > -#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ > - > -/* > - * Mount flags > - */ > -#define EXT3_MOUNT_CHECK 0x00001 /* Do mount-time checks */ > -/* EXT3_MOUNT_OLDALLOC was there */ > -#define EXT3_MOUNT_GRPID 0x00004 /* Create files with directory's group */ > -#define EXT3_MOUNT_DEBUG 0x00008 /* Some debugging messages */ > -#define EXT3_MOUNT_ERRORS_CONT 0x00010 /* Continue on errors */ > -#define EXT3_MOUNT_ERRORS_RO 0x00020 /* Remount fs ro on errors */ > -#define EXT3_MOUNT_ERRORS_PANIC 0x00040 /* Panic on errors */ > -#define EXT3_MOUNT_MINIX_DF 0x00080 /* Mimics the Minix statfs */ > -#define EXT3_MOUNT_NOLOAD 0x00100 /* Don't use existing journal*/ > -#define EXT3_MOUNT_ABORT 0x00200 /* Fatal error detected */ > -#define EXT3_MOUNT_DATA_FLAGS 0x00C00 /* Mode for data writes: */ > -#define EXT3_MOUNT_JOURNAL_DATA 0x00400 /* Write data to journal */ > -#define EXT3_MOUNT_ORDERED_DATA 0x00800 /* Flush data before commit */ > -#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00 /* No data ordering */ > -#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ > -#define EXT3_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ > -#define EXT3_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ > -#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ > -#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ > -#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ > -#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ > -#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ > -#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ > -#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write > - * error in ordered mode */ > - > -/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ > -#ifndef _LINUX_EXT2_FS_H > -#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt > -#define set_opt(o, opt) o |= EXT3_MOUNT_##opt > -#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt & \ > - EXT3_MOUNT_##opt) > -#else > -#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD > -#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT > -#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS > -#endif > - > -#define ext3_set_bit __set_bit_le > -#define ext3_set_bit_atomic ext2_set_bit_atomic > -#define ext3_clear_bit __clear_bit_le > -#define ext3_clear_bit_atomic ext2_clear_bit_atomic > -#define ext3_test_bit test_bit_le > -#define ext3_find_next_zero_bit find_next_zero_bit_le > - > -/* > - * Maximal mount counts between two filesystem checks > - */ > -#define EXT3_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ > -#define EXT3_DFL_CHECKINTERVAL 0 /* Don't use interval check */ > - > -/* > - * Behaviour when detecting errors > - */ > -#define EXT3_ERRORS_CONTINUE 1 /* Continue execution */ > -#define EXT3_ERRORS_RO 2 /* Remount fs read-only */ > -#define EXT3_ERRORS_PANIC 3 /* Panic */ > -#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE > - > -/* > - * Structure of the super block > - */ > -struct ext3_super_block { > -/*00*/ __le32 s_inodes_count; /* Inodes count */ > - __le32 s_blocks_count; /* Blocks count */ > - __le32 s_r_blocks_count; /* Reserved blocks count */ > - __le32 s_free_blocks_count; /* Free blocks count */ > -/*10*/ __le32 s_free_inodes_count; /* Free inodes count */ > - __le32 s_first_data_block; /* First Data Block */ > - __le32 s_log_block_size; /* Block size */ > - __le32 s_log_frag_size; /* Fragment size */ > -/*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ > - __le32 s_frags_per_group; /* # Fragments per group */ > - __le32 s_inodes_per_group; /* # Inodes per group */ > - __le32 s_mtime; /* Mount time */ > -/*30*/ __le32 s_wtime; /* Write time */ > - __le16 s_mnt_count; /* Mount count */ > - __le16 s_max_mnt_count; /* Maximal mount count */ > - __le16 s_magic; /* Magic signature */ > - __le16 s_state; /* File system state */ > - __le16 s_errors; /* Behaviour when detecting errors */ > - __le16 s_minor_rev_level; /* minor revision level */ > -/*40*/ __le32 s_lastcheck; /* time of last check */ > - __le32 s_checkinterval; /* max. time between checks */ > - __le32 s_creator_os; /* OS */ > - __le32 s_rev_level; /* Revision level */ > -/*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */ > - __le16 s_def_resgid; /* Default gid for reserved blocks */ > - /* > - * These fields are for EXT3_DYNAMIC_REV superblocks only. > - * > - * Note: the difference between the compatible feature set and > - * the incompatible feature set is that if there is a bit set > - * in the incompatible feature set that the kernel doesn't > - * know about, it should refuse to mount the filesystem. > - * > - * e2fsck's requirements are more strict; if it doesn't know > - * about a feature in either the compatible or incompatible > - * feature set, it must abort and not try to meddle with > - * things it doesn't understand... > - */ > - __le32 s_first_ino; /* First non-reserved inode */ > - __le16 s_inode_size; /* size of inode structure */ > - __le16 s_block_group_nr; /* block group # of this superblock */ > - __le32 s_feature_compat; /* compatible feature set */ > -/*60*/ __le32 s_feature_incompat; /* incompatible feature set */ > - __le32 s_feature_ro_compat; /* readonly-compatible feature set */ > -/*68*/ __u8 s_uuid[16]; /* 128-bit uuid for volume */ > -/*78*/ char s_volume_name[16]; /* volume name */ > -/*88*/ char s_last_mounted[64]; /* directory where last mounted */ > -/*C8*/ __le32 s_algorithm_usage_bitmap; /* For compression */ > - /* > - * Performance hints. Directory preallocation should only > - * happen if the EXT3_FEATURE_COMPAT_DIR_PREALLOC flag is on. > - */ > - __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ > - __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ > - __le16 s_reserved_gdt_blocks; /* Per group desc for online growth */ > - /* > - * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. > - */ > -/*D0*/ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ > -/*E0*/ __le32 s_journal_inum; /* inode number of journal file */ > - __le32 s_journal_dev; /* device number of journal file */ > - __le32 s_last_orphan; /* start of list of inodes to delete */ > - __le32 s_hash_seed[4]; /* HTREE hash seed */ > - __u8 s_def_hash_version; /* Default hash version to use */ > - __u8 s_reserved_char_pad; > - __u16 s_reserved_word_pad; > - __le32 s_default_mount_opts; > - __le32 s_first_meta_bg; /* First metablock block group */ > - __le32 s_mkfs_time; /* When the filesystem was created */ > - __le32 s_jnl_blocks[17]; /* Backup of the journal inode */ > - /* 64bit support valid if EXT4_FEATURE_COMPAT_64BIT */ > -/*150*/ __le32 s_blocks_count_hi; /* Blocks count */ > - __le32 s_r_blocks_count_hi; /* Reserved blocks count */ > - __le32 s_free_blocks_count_hi; /* Free blocks count */ > - __le16 s_min_extra_isize; /* All inodes have at least # bytes */ > - __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ > - __le32 s_flags; /* Miscellaneous flags */ > - __le16 s_raid_stride; /* RAID stride */ > - __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ > - __le64 s_mmp_block; /* Block for multi-mount protection */ > - __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ > - __u8 s_log_groups_per_flex; /* FLEX_BG group size */ > - __u8 s_reserved_char_pad2; > - __le16 s_reserved_pad; > - __u32 s_reserved[162]; /* Padding to the end of the block */ > -}; > - > -/* data type for block offset of block group */ > -typedef int ext3_grpblk_t; > - > -/* data type for filesystem-wide blocks number */ > -typedef unsigned long ext3_fsblk_t; > - > -#define E3FSBLK "%lu" > - > -struct ext3_reserve_window { > - ext3_fsblk_t _rsv_start; /* First byte reserved */ > - ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ > -}; > - > -struct ext3_reserve_window_node { > - struct rb_node rsv_node; > - __u32 rsv_goal_size; > - __u32 rsv_alloc_hit; > - struct ext3_reserve_window rsv_window; > -}; > - > -struct ext3_block_alloc_info { > - /* information about reservation window */ > - struct ext3_reserve_window_node rsv_window_node; > - /* > - * was i_next_alloc_block in ext3_inode_info > - * is the logical (file-relative) number of the > - * most-recently-allocated block in this file. > - * We use this for detecting linearly ascending allocation requests. > - */ > - __u32 last_alloc_logical_block; > - /* > - * Was i_next_alloc_goal in ext3_inode_info > - * is the *physical* companion to i_next_alloc_block. > - * it the physical block number of the block which was most-recentl > - * allocated to this file. This give us the goal (target) for the next > - * allocation when we detect linearly ascending requests. > - */ > - ext3_fsblk_t last_alloc_physical_block; > -}; > - > -#define rsv_start rsv_window._rsv_start > -#define rsv_end rsv_window._rsv_end > - > -/* > - * third extended file system inode data in memory > - */ > -struct ext3_inode_info { > - __le32 i_data[15]; /* unconverted */ > - __u32 i_flags; > -#ifdef EXT3_FRAGMENTS > - __u32 i_faddr; > - __u8 i_frag_no; > - __u8 i_frag_size; > -#endif > - ext3_fsblk_t i_file_acl; > - __u32 i_dir_acl; > - __u32 i_dtime; > - > - /* > - * i_block_group is the number of the block group which contains > - * this file's inode. Constant across the lifetime of the inode, > - * it is ued for making block allocation decisions - we try to > - * place a file's data blocks near its inode block, and new inodes > - * near to their parent directory's inode. > - */ > - __u32 i_block_group; > - unsigned long i_state_flags; /* Dynamic state flags for ext3 */ > - > - /* block reservation info */ > - struct ext3_block_alloc_info *i_block_alloc_info; > - > - __u32 i_dir_start_lookup; > -#ifdef CONFIG_EXT3_FS_XATTR > - /* > - * Extended attributes can be read independently of the main file > - * data. Taking i_mutex even when reading would cause contention > - * between readers of EAs and writers of regular file data, so > - * instead we synchronize on xattr_sem when reading or changing > - * EAs. > - */ > - struct rw_semaphore xattr_sem; > -#endif > - > - struct list_head i_orphan; /* unlinked but open inodes */ > - > - /* > - * i_disksize keeps track of what the inode size is ON DISK, not > - * in memory. During truncate, i_size is set to the new size by > - * the VFS prior to calling ext3_truncate(), but the filesystem won't > - * set i_disksize to 0 until the truncate is actually under way. > - * > - * The intent is that i_disksize always represents the blocks which > - * are used by this file. This allows recovery to restart truncate > - * on orphans if we crash during truncate. We actually write i_disksize > - * into the on-disk inode when writing inodes out, instead of i_size. > - * > - * The only time when i_disksize and i_size may be different is when > - * a truncate is in progress. The only things which change i_disksize > - * are ext3_get_block (growth) and ext3_truncate (shrinkth). > - */ > - loff_t i_disksize; > - > - /* on-disk additional length */ > - __u16 i_extra_isize; > - > - /* > - * truncate_mutex is for serialising ext3_truncate() against > - * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's > - * data tree are chopped off during truncate. We can't do that in > - * ext3 because whenever we perform intermediate commits during > - * truncate, the inode and all the metadata blocks *must* be in a > - * consistent state which allows truncation of the orphans to restart > - * during recovery. Hence we must fix the get_block-vs-truncate race > - * by other means, so we have truncate_mutex. > - */ > - struct mutex truncate_mutex; > - > - /* > - * Transactions that contain inode's metadata needed to complete > - * fsync and fdatasync, respectively. > - */ > - atomic_t i_sync_tid; > - atomic_t i_datasync_tid; > - > - struct inode vfs_inode; > -}; > - > -/* > - * third extended-fs super-block data in memory > - */ > -struct ext3_sb_info { > - unsigned long s_frag_size; /* Size of a fragment in bytes */ > - unsigned long s_frags_per_block;/* Number of fragments per block */ > - unsigned long s_inodes_per_block;/* Number of inodes per block */ > - unsigned long s_frags_per_group;/* Number of fragments in a group */ > - unsigned long s_blocks_per_group;/* Number of blocks in a group */ > - unsigned long s_inodes_per_group;/* Number of inodes in a group */ > - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ > - unsigned long s_gdb_count; /* Number of group descriptor blocks */ > - unsigned long s_desc_per_block; /* Number of group descriptors per block */ > - unsigned long s_groups_count; /* Number of groups in the fs */ > - unsigned long s_overhead_last; /* Last calculated overhead */ > - unsigned long s_blocks_last; /* Last seen block count */ > - struct buffer_head * s_sbh; /* Buffer containing the super block */ > - struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ > - struct buffer_head ** s_group_desc; > - unsigned long s_mount_opt; > - ext3_fsblk_t s_sb_block; > - uid_t s_resuid; > - gid_t s_resgid; > - unsigned short s_mount_state; > - unsigned short s_pad; > - int s_addr_per_block_bits; > - int s_desc_per_block_bits; > - int s_inode_size; > - int s_first_ino; > - spinlock_t s_next_gen_lock; > - u32 s_next_generation; > - u32 s_hash_seed[4]; > - int s_def_hash_version; > - int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ > - struct percpu_counter s_freeblocks_counter; > - struct percpu_counter s_freeinodes_counter; > - struct percpu_counter s_dirs_counter; > - struct blockgroup_lock *s_blockgroup_lock; > - > - /* root of the per fs reservation window tree */ > - spinlock_t s_rsv_window_lock; > - struct rb_root s_rsv_window_root; > - struct ext3_reserve_window_node s_rsv_window_head; > - > - /* Journaling */ > - struct inode * s_journal_inode; > - struct journal_s * s_journal; > - struct list_head s_orphan; > - struct mutex s_orphan_lock; > - struct mutex s_resize_lock; > - unsigned long s_commit_interval; > - struct block_device *journal_bdev; > -#ifdef CONFIG_QUOTA > - char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ > - int s_jquota_fmt; /* Format of quota to use */ > -#endif > -}; > - > -static inline spinlock_t * > -sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) > -{ > - return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); > -} > - > -static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) > -{ > - return sb->s_fs_info; > -} > -static inline struct ext3_inode_info *EXT3_I(struct inode *inode) > -{ > - return container_of(inode, struct ext3_inode_info, vfs_inode); > -} > - > -static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) > -{ > - return ino == EXT3_ROOT_INO || > - ino == EXT3_JOURNAL_INO || > - ino == EXT3_RESIZE_INO || > - (ino >= EXT3_FIRST_INO(sb) && > - ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); > -} > - > -/* > - * Inode dynamic state flags > - */ > -enum { > - EXT3_STATE_JDATA, /* journaled data exists */ > - EXT3_STATE_NEW, /* inode is newly created */ > - EXT3_STATE_XATTR, /* has in-inode xattrs */ > - EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ > -}; > - > -static inline int ext3_test_inode_state(struct inode *inode, int bit) > -{ > - return test_bit(bit, &EXT3_I(inode)->i_state_flags); > -} > - > -static inline void ext3_set_inode_state(struct inode *inode, int bit) > -{ > - set_bit(bit, &EXT3_I(inode)->i_state_flags); > -} > - > -static inline void ext3_clear_inode_state(struct inode *inode, int bit) > -{ > - clear_bit(bit, &EXT3_I(inode)->i_state_flags); > -} > - > -#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime > - > -/* > - * Codes for operating systems > - */ > -#define EXT3_OS_LINUX 0 > -#define EXT3_OS_HURD 1 > -#define EXT3_OS_MASIX 2 > -#define EXT3_OS_FREEBSD 3 > -#define EXT3_OS_LITES 4 > - > -/* > - * Revision levels > - */ > -#define EXT3_GOOD_OLD_REV 0 /* The good old (original) format */ > -#define EXT3_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ > - > -#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV > -#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV > - > -#define EXT3_GOOD_OLD_INODE_SIZE 128 > - > -/* > - * Feature set definitions > - */ > - > -#define EXT3_HAS_COMPAT_FEATURE(sb,mask) \ > - ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) > -#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask) \ > - ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) > -#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask) \ > - ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) > -#define EXT3_SET_COMPAT_FEATURE(sb,mask) \ > - EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) > -#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask) \ > - EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) > -#define EXT3_SET_INCOMPAT_FEATURE(sb,mask) \ > - EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) > -#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask) \ > - EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) > -#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ > - EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) > -#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask) \ > - EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) > - > -#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001 > -#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002 > -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 > -#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008 > -#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010 > -#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020 > - > -#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 > -#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 > -#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 > - > -#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001 > -#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 > -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ > -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ > -#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010 > - > -#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR > -#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ > - EXT3_FEATURE_INCOMPAT_RECOVER| \ > - EXT3_FEATURE_INCOMPAT_META_BG) > -#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ > - EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ > - EXT3_FEATURE_RO_COMPAT_BTREE_DIR) > - > -/* > - * Default values for user and/or group using reserved blocks > - */ > -#define EXT3_DEF_RESUID 0 > -#define EXT3_DEF_RESGID 0 > - > -/* > - * Default mount options > - */ > -#define EXT3_DEFM_DEBUG 0x0001 > -#define EXT3_DEFM_BSDGROUPS 0x0002 > -#define EXT3_DEFM_XATTR_USER 0x0004 > -#define EXT3_DEFM_ACL 0x0008 > -#define EXT3_DEFM_UID16 0x0010 > -#define EXT3_DEFM_JMODE 0x0060 > -#define EXT3_DEFM_JMODE_DATA 0x0020 > -#define EXT3_DEFM_JMODE_ORDERED 0x0040 > -#define EXT3_DEFM_JMODE_WBACK 0x0060 > - > -/* > - * Structure of a directory entry > - */ > -#define EXT3_NAME_LEN 255 > - > -struct ext3_dir_entry { > - __le32 inode; /* Inode number */ > - __le16 rec_len; /* Directory entry length */ > - __le16 name_len; /* Name length */ > - char name[EXT3_NAME_LEN]; /* File name */ > -}; > - > -/* > - * The new version of the directory entry. Since EXT3 structures are > - * stored in intel byte order, and the name_len field could never be > - * bigger than 255 chars, it's safe to reclaim the extra byte for the > - * file_type field. > - */ > -struct ext3_dir_entry_2 { > - __le32 inode; /* Inode number */ > - __le16 rec_len; /* Directory entry length */ > - __u8 name_len; /* Name length */ > - __u8 file_type; > - char name[EXT3_NAME_LEN]; /* File name */ > -}; > - > -/* > - * Ext3 directory file types. Only the low 3 bits are used. The > - * other bits are reserved for now. > - */ > -#define EXT3_FT_UNKNOWN 0 > -#define EXT3_FT_REG_FILE 1 > -#define EXT3_FT_DIR 2 > -#define EXT3_FT_CHRDEV 3 > -#define EXT3_FT_BLKDEV 4 > -#define EXT3_FT_FIFO 5 > -#define EXT3_FT_SOCK 6 > -#define EXT3_FT_SYMLINK 7 > - > -#define EXT3_FT_MAX 8 > - > -/* > - * EXT3_DIR_PAD defines the directory entries boundaries > - * > - * NOTE: It must be a multiple of 4 > - */ > -#define EXT3_DIR_PAD 4 > -#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) > -#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ > - ~EXT3_DIR_ROUND) > -#define EXT3_MAX_REC_LEN ((1<<16)-1) > - > -/* > - * Tests against MAX_REC_LEN etc were put in place for 64k block > - * sizes; if that is not possible on this arch, we can skip > - * those tests and speed things up. > - */ > -static inline unsigned ext3_rec_len_from_disk(__le16 dlen) > -{ > - unsigned len = le16_to_cpu(dlen); > - > -#if (PAGE_CACHE_SIZE >= 65536) > - if (len == EXT3_MAX_REC_LEN) > - return 1 << 16; > -#endif > - return len; > -} > - > -static inline __le16 ext3_rec_len_to_disk(unsigned len) > -{ > -#if (PAGE_CACHE_SIZE >= 65536) > - if (len == (1 << 16)) > - return cpu_to_le16(EXT3_MAX_REC_LEN); > - else if (len > (1 << 16)) > - BUG(); > -#endif > - return cpu_to_le16(len); > -} > - > -/* > - * Hash Tree Directory indexing > - * (c) Daniel Phillips, 2001 > - */ > - > -#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ > - EXT3_FEATURE_COMPAT_DIR_INDEX) && \ > - (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) > -#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) > -#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) > - > -/* Legal values for the dx_root hash_version field: */ > - > -#define DX_HASH_LEGACY 0 > -#define DX_HASH_HALF_MD4 1 > -#define DX_HASH_TEA 2 > -#define DX_HASH_LEGACY_UNSIGNED 3 > -#define DX_HASH_HALF_MD4_UNSIGNED 4 > -#define DX_HASH_TEA_UNSIGNED 5 > - > -/* hash info structure used by the directory hash */ > -struct dx_hash_info > -{ > - u32 hash; > - u32 minor_hash; > - int hash_version; > - u32 *seed; > -}; > - > -#define EXT3_HTREE_EOF 0x7fffffff > - > -/* > - * Control parameters used by ext3_htree_next_block > - */ > -#define HASH_NB_ALWAYS 1 > - > - > -/* > - * Describe an inode's exact location on disk and in memory > - */ > -struct ext3_iloc > -{ > - struct buffer_head *bh; > - unsigned long offset; > - unsigned long block_group; > -}; > - > -static inline struct ext3_inode *ext3_raw_inode(struct ext3_iloc *iloc) > -{ > - return (struct ext3_inode *) (iloc->bh->b_data + iloc->offset); > -} > - > -/* > - * This structure is stuffed into the struct file's private_data field > - * for directories. It is where we put information so that we can do > - * readdir operations in hash tree order. > - */ > -struct dir_private_info { > - struct rb_root root; > - struct rb_node *curr_node; > - struct fname *extra_fname; > - loff_t last_pos; > - __u32 curr_hash; > - __u32 curr_minor_hash; > - __u32 next_hash; > -}; > - > -/* calculate the first block number of the group */ > -static inline ext3_fsblk_t > -ext3_group_first_block_no(struct super_block *sb, unsigned long group_no) > -{ > - return group_no * (ext3_fsblk_t)EXT3_BLOCKS_PER_GROUP(sb) + > - le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); > -} > - > -/* > - * Special error return code only used by dx_probe() and its callers. > - */ > -#define ERR_BAD_DX_DIR -75000 > - > -/* > - * Function prototypes > - */ > - > -/* > - * Ok, these declarations are also in but none of the > - * ext3 source programs needs to include it so they are duplicated here. > - */ > -# define NORET_TYPE /**/ > -# define ATTRIB_NORET __attribute__((noreturn)) > -# define NORET_AND noreturn, > - > -/* balloc.c */ > -extern int ext3_bg_has_super(struct super_block *sb, int group); > -extern unsigned long ext3_bg_num_gdb(struct super_block *sb, int group); > -extern ext3_fsblk_t ext3_new_block (handle_t *handle, struct inode *inode, > - ext3_fsblk_t goal, int *errp); > -extern ext3_fsblk_t ext3_new_blocks (handle_t *handle, struct inode *inode, > - ext3_fsblk_t goal, unsigned long *count, int *errp); > -extern void ext3_free_blocks (handle_t *handle, struct inode *inode, > - ext3_fsblk_t block, unsigned long count); > -extern void ext3_free_blocks_sb (handle_t *handle, struct super_block *sb, > - ext3_fsblk_t block, unsigned long count, > - unsigned long *pdquot_freed_blocks); > -extern ext3_fsblk_t ext3_count_free_blocks (struct super_block *); > -extern void ext3_check_blocks_bitmap (struct super_block *); > -extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, > - unsigned int block_group, > - struct buffer_head ** bh); > -extern int ext3_should_retry_alloc(struct super_block *sb, int *retries); > -extern void ext3_init_block_alloc_info(struct inode *); > -extern void ext3_rsv_window_add(struct super_block *sb, struct ext3_reserve_window_node *rsv); > -extern int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range); > - > -/* dir.c */ > -extern int ext3_check_dir_entry(const char *, struct inode *, > - struct ext3_dir_entry_2 *, > - struct buffer_head *, unsigned long); > -extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, > - __u32 minor_hash, > - struct ext3_dir_entry_2 *dirent); > -extern void ext3_htree_free_dir_info(struct dir_private_info *p); > - > -/* fsync.c */ > -extern int ext3_sync_file(struct file *, loff_t, loff_t, int); > - > -/* hash.c */ > -extern int ext3fs_dirhash(const char *name, int len, struct > - dx_hash_info *hinfo); > - > -/* ialloc.c */ > -extern struct inode * ext3_new_inode (handle_t *, struct inode *, > - const struct qstr *, umode_t); > -extern void ext3_free_inode (handle_t *, struct inode *); > -extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); > -extern unsigned long ext3_count_free_inodes (struct super_block *); > -extern unsigned long ext3_count_dirs (struct super_block *); > -extern void ext3_check_inodes_bitmap (struct super_block *); > -extern unsigned long ext3_count_free (struct buffer_head *, unsigned); > - > - > -/* inode.c */ > -int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, > - struct buffer_head *bh, ext3_fsblk_t blocknr); > -struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); > -struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); > -int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, > - sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result, > - int create); > - > -extern struct inode *ext3_iget(struct super_block *, unsigned long); > -extern int ext3_write_inode (struct inode *, struct writeback_control *); > -extern int ext3_setattr (struct dentry *, struct iattr *); > -extern void ext3_evict_inode (struct inode *); > -extern int ext3_sync_inode (handle_t *, struct inode *); > -extern void ext3_discard_reservation (struct inode *); > -extern void ext3_dirty_inode(struct inode *, int); > -extern int ext3_change_inode_journal_flag(struct inode *, int); > -extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); > -extern int ext3_can_truncate(struct inode *inode); > -extern void ext3_truncate(struct inode *inode); > -extern void ext3_set_inode_flags(struct inode *); > -extern void ext3_get_inode_flags(struct ext3_inode_info *); > -extern void ext3_set_aops(struct inode *inode); > -extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, > - u64 start, u64 len); > - > -/* ioctl.c */ > -extern long ext3_ioctl(struct file *, unsigned int, unsigned long); > -extern long ext3_compat_ioctl(struct file *, unsigned int, unsigned long); > - > -/* namei.c */ > -extern int ext3_orphan_add(handle_t *, struct inode *); > -extern int ext3_orphan_del(handle_t *, struct inode *); > -extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, > - __u32 start_minor_hash, __u32 *next_hash); > - > -/* resize.c */ > -extern int ext3_group_add(struct super_block *sb, > - struct ext3_new_group_data *input); > -extern int ext3_group_extend(struct super_block *sb, > - struct ext3_super_block *es, > - ext3_fsblk_t n_blocks_count); > - > -/* super.c */ > -extern __printf(3, 4) > -void ext3_error(struct super_block *, const char *, const char *, ...); > -extern void __ext3_std_error (struct super_block *, const char *, int); > -extern __printf(3, 4) > -void ext3_abort(struct super_block *, const char *, const char *, ...); > -extern __printf(3, 4) > -void ext3_warning(struct super_block *, const char *, const char *, ...); > -extern __printf(3, 4) > -void ext3_msg(struct super_block *, const char *, const char *, ...); > -extern void ext3_update_dynamic_rev (struct super_block *sb); > - > -#define ext3_std_error(sb, errno) \ > -do { \ > - if ((errno)) \ > - __ext3_std_error((sb), __func__, (errno)); \ > -} while (0) > - > -/* > - * Inodes and files operations > - */ > - > -/* dir.c */ > -extern const struct file_operations ext3_dir_operations; > - > -/* file.c */ > -extern const struct inode_operations ext3_file_inode_operations; > -extern const struct file_operations ext3_file_operations; > - > -/* namei.c */ > -extern const struct inode_operations ext3_dir_inode_operations; > -extern const struct inode_operations ext3_special_inode_operations; > - > -/* symlink.c */ > -extern const struct inode_operations ext3_symlink_inode_operations; > -extern const struct inode_operations ext3_fast_symlink_inode_operations; > - > -#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) > - > -/* Define the number of blocks we need to account to a transaction to > - * modify one block of data. > - * > - * We may have to touch one inode, one bitmap buffer, up to three > - * indirection blocks, the group and superblock summaries, and the data > - * block to complete the transaction. */ > - > -#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U > - > -/* Extended attribute operations touch at most two data buffers, > - * two bitmap buffers, and two group summaries, in addition to the inode > - * and the superblock, which are already accounted for. */ > - > -#define EXT3_XATTR_TRANS_BLOCKS 6U > - > -/* Define the minimum size for a transaction which modifies data. This > - * needs to take into account the fact that we may end up modifying two > - * quota files too (one for the group, one for the user quota). The > - * superblock only gets updated once, of course, so don't bother > - * counting that again for the quota updates. */ > - > -#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ > - EXT3_XATTR_TRANS_BLOCKS - 2 + \ > - EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) > - > -/* Delete operations potentially hit one directory's namespace plus an > - * entire inode, plus arbitrary amounts of bitmap/indirection data. Be > - * generous. We can grow the delete transaction later if necessary. */ > - > -#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) > - > -/* Define an arbitrary limit for the amount of data we will anticipate > - * writing to any given transaction. For unbounded transactions such as > - * write(2) and truncate(2) we can write more than this, but we always > - * start off at the maximum transaction size and grow the transaction > - * optimistically as we go. */ > - > -#define EXT3_MAX_TRANS_DATA 64U > - > -/* We break up a large truncate or write transaction once the handle's > - * buffer credits gets this low, we need either to extend the > - * transaction or to start a new one. Reserve enough space here for > - * inode, bitmap, superblock, group and indirection updates for at least > - * one block, plus two quota updates. Quota allocations are not > - * needed. */ > - > -#define EXT3_RESERVE_TRANS_BLOCKS 12U > - > -#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 > - > -#ifdef CONFIG_QUOTA > -/* Amount of blocks needed for quota update - we know that the structure was > - * allocated so we need to update only inode+data */ > -#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) > -/* Amount of blocks needed for quota insert/delete - we do some block writes > - * but inode, sb and group updates are done only once */ > -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ > - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) > -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ > - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) > -#else > -#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 > -#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 > -#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 > -#endif > -#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) > -#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) > -#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) > - > -int > -ext3_mark_iloc_dirty(handle_t *handle, > - struct inode *inode, > - struct ext3_iloc *iloc); > - > -/* > - * On success, We end up with an outstanding reference count against > - * iloc->bh. This _must_ be cleaned up later. > - */ > - > -int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, > - struct ext3_iloc *iloc); > - > -int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); > - > -/* > - * Wrapper functions with which ext3 calls into JBD. The intent here is > - * to allow these to be turned into appropriate stubs so ext3 can control > - * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't > - * been done yet. > - */ > - > -static inline void ext3_journal_release_buffer(handle_t *handle, > - struct buffer_head *bh) > -{ > - journal_release_buffer(handle, bh); > -} > - > -void ext3_journal_abort_handle(const char *caller, const char *err_fn, > - struct buffer_head *bh, handle_t *handle, int err); > - > -int __ext3_journal_get_undo_access(const char *where, handle_t *handle, > - struct buffer_head *bh); > - > -int __ext3_journal_get_write_access(const char *where, handle_t *handle, > - struct buffer_head *bh); > - > -int __ext3_journal_forget(const char *where, handle_t *handle, > - struct buffer_head *bh); > - > -int __ext3_journal_revoke(const char *where, handle_t *handle, > - unsigned long blocknr, struct buffer_head *bh); > - > -int __ext3_journal_get_create_access(const char *where, > - handle_t *handle, struct buffer_head *bh); > - > -int __ext3_journal_dirty_metadata(const char *where, > - handle_t *handle, struct buffer_head *bh); > - > -#define ext3_journal_get_undo_access(handle, bh) \ > - __ext3_journal_get_undo_access(__func__, (handle), (bh)) > -#define ext3_journal_get_write_access(handle, bh) \ > - __ext3_journal_get_write_access(__func__, (handle), (bh)) > -#define ext3_journal_revoke(handle, blocknr, bh) \ > - __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) > -#define ext3_journal_get_create_access(handle, bh) \ > - __ext3_journal_get_create_access(__func__, (handle), (bh)) > -#define ext3_journal_dirty_metadata(handle, bh) \ > - __ext3_journal_dirty_metadata(__func__, (handle), (bh)) > -#define ext3_journal_forget(handle, bh) \ > - __ext3_journal_forget(__func__, (handle), (bh)) > - > -int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); > - > -handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); > -int __ext3_journal_stop(const char *where, handle_t *handle); > - > -static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) > -{ > - return ext3_journal_start_sb(inode->i_sb, nblocks); > -} > - > -#define ext3_journal_stop(handle) \ > - __ext3_journal_stop(__func__, (handle)) > - > -static inline handle_t *ext3_journal_current_handle(void) > -{ > - return journal_current_handle(); > -} > - > -static inline int ext3_journal_extend(handle_t *handle, int nblocks) > -{ > - return journal_extend(handle, nblocks); > -} > - > -static inline int ext3_journal_restart(handle_t *handle, int nblocks) > -{ > - return journal_restart(handle, nblocks); > -} > - > -static inline int ext3_journal_blocks_per_page(struct inode *inode) > -{ > - return journal_blocks_per_page(inode); > -} > - > -static inline int ext3_journal_force_commit(journal_t *journal) > -{ > - return journal_force_commit(journal); > -} > - > -/* super.c */ > -int ext3_force_commit(struct super_block *sb); > - > -static inline int ext3_should_journal_data(struct inode *inode) > -{ > - if (!S_ISREG(inode->i_mode)) > - return 1; > - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) > - return 1; > - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > - return 1; > - return 0; > -} > - > -static inline int ext3_should_order_data(struct inode *inode) > -{ > - if (!S_ISREG(inode->i_mode)) > - return 0; > - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > - return 0; > - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) > - return 1; > - return 0; > -} > - > -static inline int ext3_should_writeback_data(struct inode *inode) > -{ > - if (!S_ISREG(inode->i_mode)) > - return 0; > - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) > - return 0; > - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) > - return 1; > - return 0; > -} > - > -#include > - > diff --git a/instrumentation/events/mainline/jbd.h b/instrumentation/events/mainline/jbd.h > index aff64d8..da6f259 100644 > --- a/instrumentation/events/mainline/jbd.h > +++ b/instrumentation/events/mainline/jbd.h > @@ -36,19 +36,17 @@ DECLARE_EVENT_CLASS(jbd_commit, > > TP_STRUCT__entry( > __field( dev_t, dev ) > - __field( char, sync_commit ) > __field( int, transaction ) > ), > > TP_fast_assign( > __entry->dev = journal->j_fs_dev->bd_dev; > - __entry->sync_commit = commit_transaction->t_synchronous_commit; > __entry->transaction = commit_transaction->t_tid; > ), > > - TP_printk("dev %d,%d transaction %d sync %d", > + TP_printk("dev %d,%d transaction %d", > MAJOR(__entry->dev), MINOR(__entry->dev), > - __entry->transaction, __entry->sync_commit) > + __entry->transaction) > ); > > DEFINE_EVENT(jbd_commit, jbd_start_commit, > @@ -87,19 +85,17 @@ TRACE_EVENT(jbd_drop_transaction, > > TP_STRUCT__entry( > __field( dev_t, dev ) > - __field( char, sync_commit ) > __field( int, transaction ) > ), > > TP_fast_assign( > __entry->dev = journal->j_fs_dev->bd_dev; > - __entry->sync_commit = commit_transaction->t_synchronous_commit; > __entry->transaction = commit_transaction->t_tid; > ), > > - TP_printk("dev %d,%d transaction %d sync %d", > + TP_printk("dev %d,%d transaction %d", > MAJOR(__entry->dev), MINOR(__entry->dev), > - __entry->transaction, __entry->sync_commit) > + __entry->transaction) > ); > > TRACE_EVENT(jbd_end_commit, > @@ -109,21 +105,19 @@ TRACE_EVENT(jbd_end_commit, > > TP_STRUCT__entry( > __field( dev_t, dev ) > - __field( char, sync_commit ) > __field( int, transaction ) > __field( int, head ) > ), > > TP_fast_assign( > __entry->dev = journal->j_fs_dev->bd_dev; > - __entry->sync_commit = commit_transaction->t_synchronous_commit; > __entry->transaction = commit_transaction->t_tid; > __entry->head = journal->j_tail_sequence; > ), > > - TP_printk("dev %d,%d transaction %d sync %d head %d", > + TP_printk("dev %d,%d transaction %d head %d", > MAJOR(__entry->dev), MINOR(__entry->dev), > - __entry->transaction, __entry->sync_commit, __entry->head) > + __entry->transaction, __entry->head) > ); > > TRACE_EVENT(jbd_do_submit_data, > @@ -133,19 +127,17 @@ TRACE_EVENT(jbd_do_submit_data, > > TP_STRUCT__entry( > __field( dev_t, dev ) > - __field( char, sync_commit ) > __field( int, transaction ) > ), > > TP_fast_assign( > __entry->dev = journal->j_fs_dev->bd_dev; > - __entry->sync_commit = commit_transaction->t_synchronous_commit; > __entry->transaction = commit_transaction->t_tid; > ), > > - TP_printk("dev %d,%d transaction %d sync %d", > + TP_printk("dev %d,%d transaction %d", > MAJOR(__entry->dev), MINOR(__entry->dev), > - __entry->transaction, __entry->sync_commit) > + __entry->transaction) > ); > > TRACE_EVENT(jbd_cleanup_journal_tail, > @@ -177,24 +169,23 @@ TRACE_EVENT(jbd_cleanup_journal_tail, > __entry->block_nr, __entry->freed) > ); > > -TRACE_EVENT(jbd_update_superblock_end, > - TP_PROTO(journal_t *journal, int wait), > +TRACE_EVENT(journal_write_superblock, > + TP_PROTO(journal_t *journal, int write_op), > > - TP_ARGS(journal, wait), > + TP_ARGS(journal, write_op), > > TP_STRUCT__entry( > __field( dev_t, dev ) > - __field( int, wait ) > + __field( int, write_op ) > ), > > TP_fast_assign( > __entry->dev = journal->j_fs_dev->bd_dev; > - __entry->wait = wait; > + __entry->write_op = write_op; > ), > > - TP_printk("dev %d,%d wait %d", > - MAJOR(__entry->dev), MINOR(__entry->dev), > - __entry->wait) > + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), > + MINOR(__entry->dev), __entry->write_op) > ); > > #endif /* _TRACE_JBD_H */ > diff --git a/instrumentation/events/mainline/jbd2.h b/instrumentation/events/mainline/jbd2.h > index 7596441..127993d 100644 > --- a/instrumentation/events/mainline/jbd2.h > +++ b/instrumentation/events/mainline/jbd2.h > @@ -81,6 +81,13 @@ DEFINE_EVENT(jbd2_commit, jbd2_commit_logging, > TP_ARGS(journal, commit_transaction) > ); > > +DEFINE_EVENT(jbd2_commit, jbd2_drop_transaction, > + > + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > + > + TP_ARGS(journal, commit_transaction) > +); > + > TRACE_EVENT(jbd2_end_commit, > TP_PROTO(journal_t *journal, transaction_t *commit_transaction), > > @@ -200,7 +207,7 @@ TRACE_EVENT(jbd2_checkpoint_stats, > __entry->forced_to_close, __entry->written, __entry->dropped) > ); > > -TRACE_EVENT(jbd2_cleanup_journal_tail, > +TRACE_EVENT(jbd2_update_log_tail, > > TP_PROTO(journal_t *journal, tid_t first_tid, > unsigned long block_nr, unsigned long freed), > @@ -229,6 +236,26 @@ TRACE_EVENT(jbd2_cleanup_journal_tail, > __entry->block_nr, __entry->freed) > ); > > +TRACE_EVENT(jbd2_write_superblock, > + > + TP_PROTO(journal_t *journal, int write_op), > + > + TP_ARGS(journal, write_op), > + > + TP_STRUCT__entry( > + __field( dev_t, dev ) > + __field( int, write_op ) > + ), > + > + TP_fast_assign( > + __entry->dev = journal->j_fs_dev->bd_dev; > + __entry->write_op = write_op; > + ), > + > + TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev), > + MINOR(__entry->dev), __entry->write_op) > +); > + > #endif /* _TRACE_JBD2_H */ > > /* This part must be outside protection */ > diff --git a/instrumentation/events/mainline/kmem.h b/instrumentation/events/mainline/kmem.h > index a9c87ad..08fa272 100644 > --- a/instrumentation/events/mainline/kmem.h > +++ b/instrumentation/events/mainline/kmem.h > @@ -147,7 +147,7 @@ DEFINE_EVENT(kmem_free, kmem_cache_free, > TP_ARGS(call_site, ptr) > ); > > -TRACE_EVENT(mm_page_free_direct, > +TRACE_EVENT(mm_page_free, > > TP_PROTO(struct page *page, unsigned int order), > > @@ -169,7 +169,7 @@ TRACE_EVENT(mm_page_free_direct, > __entry->order) > ); > > -TRACE_EVENT(mm_pagevec_free, > +TRACE_EVENT(mm_page_free_batched, > > TP_PROTO(struct page *page, int cold), > > @@ -214,7 +214,7 @@ TRACE_EVENT(mm_page_alloc, > > TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s", > __entry->page, > - page_to_pfn(__entry->page), > + __entry->page ? page_to_pfn(__entry->page) : 0, > __entry->order, > __entry->migratetype, > show_gfp_flags(__entry->gfp_flags)) > @@ -240,7 +240,7 @@ DECLARE_EVENT_CLASS(mm_page, > > TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d", > __entry->page, > - page_to_pfn(__entry->page), > + __entry->page ? page_to_pfn(__entry->page) : 0, > __entry->order, > __entry->migratetype, > __entry->order == 0) > diff --git a/instrumentation/events/mainline/power.h b/instrumentation/events/mainline/power.h > index 1bcc2a8..0c97838 100644 > --- a/instrumentation/events/mainline/power.h > +++ b/instrumentation/events/mainline/power.h > @@ -65,7 +65,40 @@ TRACE_EVENT(machine_suspend, > TP_printk("state=%lu", (unsigned long)__entry->state) > ); > > -/* This code will be removed after deprecation time exceeded (2.6.41) */ > +DECLARE_EVENT_CLASS(wakeup_source, > + > + TP_PROTO(const char *name, unsigned int state), > + > + TP_ARGS(name, state), > + > + TP_STRUCT__entry( > + __string( name, name ) > + __field( u64, state ) > + ), > + > + TP_fast_assign( > + __assign_str(name, name); > + __entry->state = state; > + ), > + > + TP_printk("%s state=0x%lx", __get_str(name), > + (unsigned long)__entry->state) > +); > + > +DEFINE_EVENT(wakeup_source, wakeup_source_activate, > + > + TP_PROTO(const char *name, unsigned int state), > + > + TP_ARGS(name, state) > +); > + > +DEFINE_EVENT(wakeup_source, wakeup_source_deactivate, > + > + TP_PROTO(const char *name, unsigned int state), > + > + TP_ARGS(name, state) > +); > + > #ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED > > /* > @@ -151,6 +184,8 @@ enum { > events get removed */ > static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {}; > static inline void trace_power_end(u64 cpuid) {}; > +static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {}; > +static inline void trace_power_end_rcuidle(u64 cpuid) {}; > static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {}; > #endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */ > > diff --git a/instrumentation/events/mainline/sched.h b/instrumentation/events/mainline/sched.h > index 6700ecc..ea7a203 100644 > --- a/instrumentation/events/mainline/sched.h > +++ b/instrumentation/events/mainline/sched.h > @@ -6,6 +6,7 @@ > > #include > #include > +#include > > /* > * Tracepoint for calling kthread_stop, performed to end a kthread: > @@ -100,7 +101,7 @@ static inline long __trace_sched_switch_state(struct task_struct *p) > * For all intents and purposes a preempted task is a running task. > */ > if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) > - state = TASK_RUNNING; > + state = TASK_RUNNING | TASK_STATE_MAX; > #endif > > return state; > @@ -137,13 +138,14 @@ TRACE_EVENT(sched_switch, > __entry->next_prio = next->prio; > ), > > - TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_pid=%d next_prio=%d", > + TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", > __entry->prev_comm, __entry->prev_pid, __entry->prev_prio, > - __entry->prev_state ? > - __print_flags(__entry->prev_state, "|", > + __entry->prev_state & (TASK_STATE_MAX-1) ? > + __print_flags(__entry->prev_state & (TASK_STATE_MAX-1), "|", > { 1, "S"} , { 2, "D" }, { 4, "T" }, { 8, "t" }, > { 16, "Z" }, { 32, "X" }, { 64, "x" }, > { 128, "W" }) : "R", > + __entry->prev_state & TASK_STATE_MAX ? "+" : "", > __entry->next_comm, __entry->next_pid, __entry->next_prio) > ); > > @@ -356,6 +358,13 @@ DEFINE_EVENT(sched_stat_template, sched_stat_iowait, > TP_ARGS(tsk, delay)); > > /* > + * Tracepoint for accounting blocked time (time the task is in uninterruptible). > + */ > +DEFINE_EVENT(sched_stat_template, sched_stat_blocked, > + TP_PROTO(struct task_struct *tsk, u64 delay), > + TP_ARGS(tsk, delay)); > + > +/* > * Tracepoint for accounting runtime (time the task is executing > * on a CPU). > */ > diff --git a/instrumentation/events/mainline/signal.h b/instrumentation/events/mainline/signal.h > index 17df434..39a8a43 100644 > --- a/instrumentation/events/mainline/signal.h > +++ b/instrumentation/events/mainline/signal.h > @@ -23,11 +23,23 @@ > } \ > } while (0) > > +#ifndef TRACE_HEADER_MULTI_READ > +enum { > + TRACE_SIGNAL_DELIVERED, > + TRACE_SIGNAL_IGNORED, > + TRACE_SIGNAL_ALREADY_PENDING, > + TRACE_SIGNAL_OVERFLOW_FAIL, > + TRACE_SIGNAL_LOSE_INFO, > +}; > +#endif > + > /** > * signal_generate - called when a signal is generated > * @sig: signal number > * @info: pointer to struct siginfo > * @task: pointer to struct task_struct > + * @group: shared or private > + * @result: TRACE_SIGNAL_* > * > * Current process sends a 'sig' signal to 'task' process with > * 'info' siginfo. If 'info' is SEND_SIG_NOINFO or SEND_SIG_PRIV, > @@ -37,9 +49,10 @@ > */ > TRACE_EVENT(signal_generate, > > - TP_PROTO(int sig, struct siginfo *info, struct task_struct *task), > + TP_PROTO(int sig, struct siginfo *info, struct task_struct *task, > + int group, int result), > > - TP_ARGS(sig, info, task), > + TP_ARGS(sig, info, task, group, result), > > TP_STRUCT__entry( > __field( int, sig ) > @@ -47,6 +60,8 @@ TRACE_EVENT(signal_generate, > __field( int, code ) > __array( char, comm, TASK_COMM_LEN ) > __field( pid_t, pid ) > + __field( int, group ) > + __field( int, result ) > ), > > TP_fast_assign( > @@ -54,11 +69,14 @@ TRACE_EVENT(signal_generate, > TP_STORE_SIGINFO(__entry, info); > memcpy(__entry->comm, task->comm, TASK_COMM_LEN); > __entry->pid = task->pid; > + __entry->group = group; > + __entry->result = result; > ), > > - TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d", > + TP_printk("sig=%d errno=%d code=%d comm=%s pid=%d grp=%d res=%d", > __entry->sig, __entry->errno, __entry->code, > - __entry->comm, __entry->pid) > + __entry->comm, __entry->pid, __entry->group, > + __entry->result) > ); > > /** > @@ -101,65 +119,6 @@ TRACE_EVENT(signal_deliver, > __entry->sa_handler, __entry->sa_flags) > ); > > -DECLARE_EVENT_CLASS(signal_queue_overflow, > - > - TP_PROTO(int sig, int group, struct siginfo *info), > - > - TP_ARGS(sig, group, info), > - > - TP_STRUCT__entry( > - __field( int, sig ) > - __field( int, group ) > - __field( int, errno ) > - __field( int, code ) > - ), > - > - TP_fast_assign( > - __entry->sig = sig; > - __entry->group = group; > - TP_STORE_SIGINFO(__entry, info); > - ), > - > - TP_printk("sig=%d group=%d errno=%d code=%d", > - __entry->sig, __entry->group, __entry->errno, __entry->code) > -); > - > -/** > - * signal_overflow_fail - called when signal queue is overflow > - * @sig: signal number > - * @group: signal to process group or not (bool) > - * @info: pointer to struct siginfo > - * > - * Kernel fails to generate 'sig' signal with 'info' siginfo, because > - * siginfo queue is overflow, and the signal is dropped. > - * 'group' is not 0 if the signal will be sent to a process group. > - * 'sig' is always one of RT signals. > - */ > -DEFINE_EVENT(signal_queue_overflow, signal_overflow_fail, > - > - TP_PROTO(int sig, int group, struct siginfo *info), > - > - TP_ARGS(sig, group, info) > -); > - > -/** > - * signal_lose_info - called when siginfo is lost > - * @sig: signal number > - * @group: signal to process group or not (bool) > - * @info: pointer to struct siginfo > - * > - * Kernel generates 'sig' signal but loses 'info' siginfo, because siginfo > - * queue is overflow. > - * 'group' is not 0 if the signal will be sent to a process group. > - * 'sig' is always one of non-RT signals. > - */ > -DEFINE_EVENT(signal_queue_overflow, signal_lose_info, > - > - TP_PROTO(int sig, int group, struct siginfo *info), > - > - TP_ARGS(sig, group, info) > -); > - > #endif /* _TRACE_SIGNAL_H */ > > /* This part must be outside protection */ > diff --git a/instrumentation/events/mainline/vmscan.h b/instrumentation/events/mainline/vmscan.h > index 36851f7..bab3b87 100644 > --- a/instrumentation/events/mainline/vmscan.h > +++ b/instrumentation/events/mainline/vmscan.h > @@ -13,7 +13,7 @@ > #define RECLAIM_WB_ANON 0x0001u > #define RECLAIM_WB_FILE 0x0002u > #define RECLAIM_WB_MIXED 0x0010u > -#define RECLAIM_WB_SYNC 0x0004u > +#define RECLAIM_WB_SYNC 0x0004u /* Unused, all reclaim async */ > #define RECLAIM_WB_ASYNC 0x0008u > > #define show_reclaim_flags(flags) \ > @@ -25,15 +25,15 @@ > {RECLAIM_WB_ASYNC, "RECLAIM_WB_ASYNC"} \ > ) : "RECLAIM_WB_NONE" > > -#define trace_reclaim_flags(page, sync) ( \ > +#define trace_reclaim_flags(page) ( \ > (page_is_file_cache(page) ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > - (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > + (RECLAIM_WB_ASYNC) \ > ) > > -#define trace_shrink_flags(file, sync) ( \ > - (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_MIXED : \ > - (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON)) | \ > - (sync & RECLAIM_MODE_SYNC ? RECLAIM_WB_SYNC : RECLAIM_WB_ASYNC) \ > +#define trace_shrink_flags(file) \ > + ( \ > + (file ? RECLAIM_WB_FILE : RECLAIM_WB_ANON) | \ > + (RECLAIM_WB_ASYNC) \ > ) > > TRACE_EVENT(mm_vmscan_kswapd_sleep, > @@ -263,22 +263,18 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > unsigned long nr_requested, > unsigned long nr_scanned, > unsigned long nr_taken, > - unsigned long nr_lumpy_taken, > - unsigned long nr_lumpy_dirty, > - unsigned long nr_lumpy_failed, > - int isolate_mode), > + isolate_mode_t isolate_mode, > + int file), > > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode), > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file), > > TP_STRUCT__entry( > __field(int, order) > __field(unsigned long, nr_requested) > __field(unsigned long, nr_scanned) > __field(unsigned long, nr_taken) > - __field(unsigned long, nr_lumpy_taken) > - __field(unsigned long, nr_lumpy_dirty) > - __field(unsigned long, nr_lumpy_failed) > - __field(int, isolate_mode) > + __field(isolate_mode_t, isolate_mode) > + __field(int, file) > ), > > TP_fast_assign( > @@ -286,21 +282,17 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template, > __entry->nr_requested = nr_requested; > __entry->nr_scanned = nr_scanned; > __entry->nr_taken = nr_taken; > - __entry->nr_lumpy_taken = nr_lumpy_taken; > - __entry->nr_lumpy_dirty = nr_lumpy_dirty; > - __entry->nr_lumpy_failed = nr_lumpy_failed; > __entry->isolate_mode = isolate_mode; > + __entry->file = file; > ), > > - TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu contig_taken=%lu contig_dirty=%lu contig_failed=%lu", > + TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d", > __entry->isolate_mode, > __entry->order, > __entry->nr_requested, > __entry->nr_scanned, > __entry->nr_taken, > - __entry->nr_lumpy_taken, > - __entry->nr_lumpy_dirty, > - __entry->nr_lumpy_failed) > + __entry->file) > ); > > DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > @@ -309,12 +301,10 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate, > unsigned long nr_requested, > unsigned long nr_scanned, > unsigned long nr_taken, > - unsigned long nr_lumpy_taken, > - unsigned long nr_lumpy_dirty, > - unsigned long nr_lumpy_failed, > - int isolate_mode), > + isolate_mode_t isolate_mode, > + int file), > > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > > ); > > @@ -324,12 +314,10 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, > unsigned long nr_requested, > unsigned long nr_scanned, > unsigned long nr_taken, > - unsigned long nr_lumpy_taken, > - unsigned long nr_lumpy_dirty, > - unsigned long nr_lumpy_failed, > - int isolate_mode), > + isolate_mode_t isolate_mode, > + int file), > > - TP_ARGS(order, nr_requested, nr_scanned, nr_taken, nr_lumpy_taken, nr_lumpy_dirty, nr_lumpy_failed, isolate_mode) > + TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file) > > ); > > @@ -389,88 +377,6 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, > show_reclaim_flags(__entry->reclaim_flags)) > ); > > -TRACE_EVENT(replace_swap_token, > - TP_PROTO(struct mm_struct *old_mm, > - struct mm_struct *new_mm), > - > - TP_ARGS(old_mm, new_mm), > - > - TP_STRUCT__entry( > - __field(struct mm_struct*, old_mm) > - __field(unsigned int, old_prio) > - __field(struct mm_struct*, new_mm) > - __field(unsigned int, new_prio) > - ), > - > - TP_fast_assign( > - __entry->old_mm = old_mm; > - __entry->old_prio = old_mm ? old_mm->token_priority : 0; > - __entry->new_mm = new_mm; > - __entry->new_prio = new_mm->token_priority; > - ), > - > - TP_printk("old_token_mm=%p old_prio=%u new_token_mm=%p new_prio=%u", > - __entry->old_mm, __entry->old_prio, > - __entry->new_mm, __entry->new_prio) > -); > - > -DECLARE_EVENT_CLASS(put_swap_token_template, > - TP_PROTO(struct mm_struct *swap_token_mm), > - > - TP_ARGS(swap_token_mm), > - > - TP_STRUCT__entry( > - __field(struct mm_struct*, swap_token_mm) > - ), > - > - TP_fast_assign( > - __entry->swap_token_mm = swap_token_mm; > - ), > - > - TP_printk("token_mm=%p", __entry->swap_token_mm) > -); > - > -DEFINE_EVENT(put_swap_token_template, put_swap_token, > - TP_PROTO(struct mm_struct *swap_token_mm), > - TP_ARGS(swap_token_mm) > -); > - > -DEFINE_EVENT_CONDITION(put_swap_token_template, disable_swap_token, > - TP_PROTO(struct mm_struct *swap_token_mm), > - TP_ARGS(swap_token_mm), > - TP_CONDITION(swap_token_mm != NULL) > -); > - > -TRACE_EVENT_CONDITION(update_swap_token_priority, > - TP_PROTO(struct mm_struct *mm, > - unsigned int old_prio, > - struct mm_struct *swap_token_mm), > - > - TP_ARGS(mm, old_prio, swap_token_mm), > - > - TP_CONDITION(mm->token_priority != old_prio), > - > - TP_STRUCT__entry( > - __field(struct mm_struct*, mm) > - __field(unsigned int, old_prio) > - __field(unsigned int, new_prio) > - __field(struct mm_struct*, swap_token_mm) > - __field(unsigned int, swap_token_prio) > - ), > - > - TP_fast_assign( > - __entry->mm = mm; > - __entry->old_prio = old_prio; > - __entry->new_prio = mm->token_priority; > - __entry->swap_token_mm = swap_token_mm; > - __entry->swap_token_prio = swap_token_mm ? swap_token_mm->token_priority : 0; > - ), > - > - TP_printk("mm=%p old_prio=%u new_prio=%u swap_token_mm=%p token_prio=%u", > - __entry->mm, __entry->old_prio, __entry->new_prio, > - __entry->swap_token_mm, __entry->swap_token_prio) > -); > - > #endif /* _TRACE_VMSCAN_H */ > > /* This part must be outside protection */ > diff --git a/probes/Makefile b/probes/Makefile > index c39a84a..ca5a9d6 100644 > --- a/probes/Makefile > +++ b/probes/Makefile > @@ -37,10 +37,13 @@ endif > endif > > ifneq ($(CONFIG_NET),) > -obj-m += lttng-probe-net.o > obj-m += lttng-probe-napi.o > obj-m += lttng-probe-skb.o > obj-m += $(shell \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 37 \) ] ; then \ > + echo "lttng-probe-net.o" ; fi;) > +obj-m += $(shell \ > if [ $(VERSION) -ge 3 -a $(PATCHLEVEL) -ge 1 ] ; then \ > echo "lttng-probe-sock.o" ; fi;) > obj-m += $(shell \ > @@ -86,12 +89,14 @@ endif > > ifneq ($(CONFIG_SCSI),) > obj-m += $(shell \ > - if [ $(VERSION) -ge 3 ] ; then \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 35 \) ] ; then \ > echo "lttng-probe-scsi.o" ; fi;) > endif > > vmscan = $(shell \ > - if [ $(VERSION) -ge 3 ] ; then \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 38 \) ] ; then \ > echo "lttng-probe-vmscan.o" ; fi;) > ifneq ($(CONFIG_SWAP),) > obj-m += $(vmscan) > @@ -102,7 +107,10 @@ endif > endif > > ifneq ($(CONFIG_LOCKDEP),) > -obj-m += lttng-probe-lock.o > +obj-m += $(shell \ > + if [ $(VERSION) -ge 3 \ > + -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 35 \) ] ; then \ > + echo "lttng-probe-lock.o" ; fi;) > endif > > ifneq ($(CONFIG_KPROBES),) > diff --git a/probes/lttng-probe-asoc.c b/probes/lttng-probe-asoc.c > index 427639f..f1981a0 100644 > --- a/probes/lttng-probe-asoc.c > +++ b/probes/lttng-probe-asoc.c > @@ -1,5 +1,5 @@ > /* > - * probes/lttng-probe-block.c > + * probes/lttng-probe-asoc.c > * > * LTTng asoc probes. > * > diff --git a/probes/lttng-probe-ext3.c b/probes/lttng-probe-ext3.c > index 0df2b67..d5842e1 100644 > --- a/probes/lttng-probe-ext3.c > +++ b/probes/lttng-probe-ext3.c > @@ -27,20 +27,16 @@ > #include > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) > -/* > - * Since 3.4 the is no linux/ext3_fs_i.h anymore. Instead we have to use > - * ext3.h from fs/ext3/ext3.h (which also includes trace/events/ext3.h) > - */ > -#include "../instrumentation/events/mainline/fs_ext3.h" > +#include <../fs/ext3/ext3.h> > #else > #include > +#endif > > /* > * Create the tracepoint static inlines from the kernel to validate that our > * trace event macros match the kernel we run on. > */ > #include > -#endif > > /* > * Create LTTng tracepoint probes. > diff --git a/probes/lttng-probe-jbd.c b/probes/lttng-probe-jbd.c > index 46911cc..9bac325 100644 > --- a/probes/lttng-probe-jbd.c > +++ b/probes/lttng-probe-jbd.c > @@ -22,7 +22,6 @@ > */ > > #include > -#include > > /* > * Create the tracepoint static inlines from the kernel to validate that our > diff --git a/probes/lttng-probe-vmscan.c b/probes/lttng-probe-vmscan.c > index 4f5739c..b78c0d6 100644 > --- a/probes/lttng-probe-vmscan.c > +++ b/probes/lttng-probe-vmscan.c > @@ -22,7 +22,6 @@ > */ > > #include > -#include > > /* > * Create the tracepoint static inlines from the kernel to validate that our > @@ -39,11 +38,6 @@ > #define CREATE_TRACE_POINTS > #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module > > -#if ((LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,38)) || \ > - LTTNG_KERNEL_RANGE(3,1,0, 3,2,0)) > -typedef int isolate_mode_t; > -#endif > - > #include "../instrumentation/events/lttng-module/vmscan.h" > > MODULE_LICENSE("GPL and additional rights"); > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From mathieu.desnoyers at efficios.com Wed Nov 28 10:51:21 2012 From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers) Date: Wed, 28 Nov 2012 10:51:21 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix a typo in lttng-probe-module name In-Reply-To: <1354113806-19089-1-git-send-email-andrew_gabbasov@mentor.com> References: <1354113806-19089-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <20121128155121.GB9266@Krystal> * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > Signed-off-by: Andrew Gabbasov Acked-by: Mathieu Desnoyers > --- > src/bin/lttng-sessiond/modprobe.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c > index f38d393..8e5cc94 100644 > --- a/src/bin/lttng-sessiond/modprobe.c > +++ b/src/bin/lttng-sessiond/modprobe.c > @@ -54,7 +54,7 @@ const struct kern_modules_param kern_modules_list[] = { > { "lttng-probe-kmem", 0 }, > { "lttng-probe-kvm", 0 }, > { "lttng-probe-lock", 0 }, > - { "lttng-probe-modules", 0 }, > + { "lttng-probe-module", 0 }, > { "lttng-probe-napi", 0 }, > { "lttng-probe-net", 0 }, > { "lttng-probe-power", 0 }, > -- > 1.7.10.4 > > > _______________________________________________ > lttng-dev mailing list > lttng-dev at lists.lttng.org > http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com From dgoulet at efficios.com Wed Nov 28 11:33:34 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 28 Nov 2012 11:33:34 -0500 Subject: [lttng-dev] [RELEASE] LTTng-tools 2.0.5 stable Message-ID: <50B63CDE.5090108@efficios.com> Greetings everyone (including LTTng elves), This is a the release of lttng-tools 2.0.5 stable. The lttng-tools project provides a session daemon (lttng-sessiond) that acts as a tracing registry, the "lttng" command line for tracing control, a lttng-ctl library for tracing control and a lttng-relayd for network streaming. Here is the full Changelog. 2012-11-28 lttng-tools 2.0.5 * Fix: Change the type of enabled in lttng_event to a signed int * Fix: Returned code when listing kernel channel * Fix: Wrong returned error code on UST enable event * Fix: consumer recv command error path * Fix: Missing libs dependencies in configure check for lttng-ust-ctl * Fix: Libtool fails to find dependent lib when cross-compiling Please feel free to email the list about any questions/comments concerning this release. Project website: http://lttng.org/lttng2.0 Download link: http://lttng.org/files/lttng-tools/lttng-tools-2.0.5.tar.bz2 (for the PGP signature, same file with .asc appended) Cheers! David From Andrew_Gabbasov at mentor.com Wed Nov 28 12:16:02 2012 From: Andrew_Gabbasov at mentor.com (Gabbasov, Andrew) Date: Wed, 28 Nov 2012 17:16:02 +0000 Subject: [lttng-dev] [PATCH lttng-modules] Update kernel probes to more detailed match to kernel versions In-Reply-To: <20121128155032.GA9266@Krystal> References: <1354096526-22098-1-git-send-email-andrew_gabbasov@mentor.com>, <20121128155032.GA9266@Krystal> Message-ID: <6C5EA58090A5ED459815C4D04C2B466F8C566A47@EU-MBX-01.mgc.mentorg.com> Hi Mathieu, > * Andrew Gabbasov (andrew_gabbasov at mentor.com) wrote: > > We have added some more ifdef's to kernel probes to more closely match > > the kernel tracepoints for different kernel versions. The changes cover > > kernel versions from 2.6.38 up to 3.7. We did not track the earlier > > versions, and they are filtered out in probes Makefile. > > > > ext3 probe was modified to use #include <../fs/ext3/ext3.h> instead of > > copying this include from kernel source to lttng-modules source. > > Using such includes (there will be more similar in other probes) > > imposes a restriction to use the full kernel source for building > > lttng-modules rather than having just kernel "include" directory, > > but it looks like full source is required anyway, at least with respect > > to Makefiles structure. May be it is worth mentioning somewhere > > in the documentation. > > > > The code was verified to compile with latest versions in all stable > > branches from 2.6.38.x to 3.6.x and 3.7-rc7. > > I get this build failure on 3.5 with this patch: > > CC [M] /home/compudj/work/lttng-modules/probes/lttng-probe-ext3.o > /home/compudj/work/lttng-modules/probes/lttng-probe-ext3.c:30:29: fatal > error: ../fs/ext3/ext3.h: No such file or directory > compilation terminated. > > can you look into it and submit a revised patch ? You must be using kernel headers for building lttng-modules (linux-headers package or something like that), right? This is what I was writing about: since ext3.h is not available in kernel's "include" directory, and in order to avoid duplicating this file in lttng-modules sources, we have to use that <../> based reference, and this requires having full kernel source for building. The same issue will later be with btrfs and ext4 probes: their necessary include files are also not available in kernel headers. Trying to duplicate these header files to lttng-modules source seems to be not a good idea, especially if we need to add many ifdef's to them to track different kernel versions. We can try to insert some checks to the Makefile and skip building those probes if we do not have full kernel sources (actually if we do not have necessary include files). Or to declare having full kernel source as a requirement for building lttng-modules. What do you think? > Also, although the README file states that we support only 3.6.38+, we > happen to also have support for kernels down to 2.6.32 with the patches > in the linux-patches/ directory applied to the appropriate kernel > versions. So it would be good that the instrumentation compiles for > those older kernels too. I promise we won't go further back than 2.6.32 > though. We'll try to add the ifdef's for earlier version down to 2.6.32 to the probes, although the additional amount of conditions makes the code overcomplicated ;-) > Thanks, > > Mathieu Thanks. Best regards, Andrew Gabbasov From dgoulet at efficios.com Wed Nov 28 12:16:59 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 28 Nov 2012 12:16:59 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Fix a typo in lttng-probe-module name In-Reply-To: <1354113806-19089-1-git-send-email-andrew_gabbasov@mentor.com> References: <1354113806-19089-1-git-send-email-andrew_gabbasov@mentor.com> Message-ID: <50B6470B.6010108@efficios.com> Merged! Thanks! Andrew Gabbasov: > Signed-off-by: Andrew Gabbasov > --- > src/bin/lttng-sessiond/modprobe.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/src/bin/lttng-sessiond/modprobe.c b/src/bin/lttng-sessiond/modprobe.c > index f38d393..8e5cc94 100644 > --- a/src/bin/lttng-sessiond/modprobe.c > +++ b/src/bin/lttng-sessiond/modprobe.c > @@ -54,7 +54,7 @@ const struct kern_modules_param kern_modules_list[] = { > { "lttng-probe-kmem", 0 }, > { "lttng-probe-kvm", 0 }, > { "lttng-probe-lock", 0 }, > - { "lttng-probe-modules", 0 }, > + { "lttng-probe-module", 0 }, > { "lttng-probe-napi", 0 }, > { "lttng-probe-net", 0 }, > { "lttng-probe-power", 0 }, From dgoulet at efficios.com Wed Nov 28 12:32:38 2012 From: dgoulet at efficios.com (David Goulet) Date: Wed, 28 Nov 2012 12:32:38 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Link test utilities against urcu-bp In-Reply-To: <20121128151359.GA2051@quintessa> References: <20121128151359.GA2051@quintessa> Message-ID: <50B64AB6.6080904@efficios.com> Hi Jon, Can you enlighten us on what setup are you using? This symbol is used by lttng-ust which is linked with -lurcu-bp so lttng-tools should not have an issue here. Are you cross-compiling ? Thanks a lot! David Jon Bernard: > The gen-ust-events utility used in several of the tests references the > 'rcu_dereference_sym' symbol contained in urcu-bp. It is necessary to link > against urcu-bp so that this symbol is resolved. > > Signed-off-by: Jon Bernard > --- > tests/tools/filtering/Makefile.am | 2 +- > tests/tools/streaming/Makefile.am | 2 +- > tests/ust/before-after/Makefile.am | 2 +- > tests/ust/high-throughput/Makefile.am | 2 +- > tests/ust/multi-session/Makefile.am | 2 +- > tests/ust/nprocesses/Makefile.am | 2 +- > 6 files changed, 6 insertions(+), 6 deletions(-) > > diff --git a/tests/tools/filtering/Makefile.am b/tests/tools/filtering/Makefile.am > index e1e715d..287effc 100644 > --- a/tests/tools/filtering/Makefile.am > +++ b/tests/tools/filtering/Makefile.am > @@ -11,7 +11,7 @@ endif > if HAVE_LIBLTTNG_UST_CTL > noinst_PROGRAMS = gen-ust-events > gen_ust_events_SOURCES = gen-ust-events.c tp.c tp.h > -gen_ust_events_LDADD = -llttng-ust > +gen_ust_events_LDADD = -llttng-ust -lurcu-bp > endif > > noinst_SCRIPTS = runall unsupported-ops invalid-filters valid-filters babelstats.pl > diff --git a/tests/tools/streaming/Makefile.am b/tests/tools/streaming/Makefile.am > index 3ff8ef0..d07baa8 100644 > --- a/tests/tools/streaming/Makefile.am > +++ b/tests/tools/streaming/Makefile.am > @@ -20,7 +20,7 @@ unit_tests_LDADD = $(LIBCOMMON) > if HAVE_LIBLTTNG_UST_CTL > noinst_PROGRAMS += gen-ust-events > gen_ust_events_SOURCES = gen-ust-events.c tp.c tp.h > -gen_ust_events_LDADD = -llttng-ust > +gen_ust_events_LDADD = -llttng-ust -lurcu-bp > endif > > noinst_SCRIPTS = runall run-ust run-kernel uri_switch > diff --git a/tests/ust/before-after/Makefile.am b/tests/ust/before-after/Makefile.am > index d197d72..80a6ba2 100644 > --- a/tests/ust/before-after/Makefile.am > +++ b/tests/ust/before-after/Makefile.am > @@ -10,7 +10,7 @@ endif > > noinst_PROGRAMS = gen-nevents > gen_nevents_SOURCES = gen-nevents.c tp.c ust_gen_nevents.h > -gen_nevents_LDADD = -llttng-ust > +gen_nevents_LDADD = -llttng-ust -lurcu-bp > > noinst_SCRIPTS = run > EXTRA_DIST = run > diff --git a/tests/ust/high-throughput/Makefile.am b/tests/ust/high-throughput/Makefile.am > index cff8fe4..74478bd 100644 > --- a/tests/ust/high-throughput/Makefile.am > +++ b/tests/ust/high-throughput/Makefile.am > @@ -10,7 +10,7 @@ endif > > noinst_PROGRAMS = gen-events > gen_events_SOURCES = main.c tp.c tp.h > -gen_events_LDADD = -llttng-ust > +gen_events_LDADD = -llttng-ust -lurcu-bp > > noinst_SCRIPTS = run > EXTRA_DIST = run > diff --git a/tests/ust/multi-session/Makefile.am b/tests/ust/multi-session/Makefile.am > index d197d72..80a6ba2 100644 > --- a/tests/ust/multi-session/Makefile.am > +++ b/tests/ust/multi-session/Makefile.am > @@ -10,7 +10,7 @@ endif > > noinst_PROGRAMS = gen-nevents > gen_nevents_SOURCES = gen-nevents.c tp.c ust_gen_nevents.h > -gen_nevents_LDADD = -llttng-ust > +gen_nevents_LDADD = -llttng-ust -lurcu-bp > > noinst_SCRIPTS = run > EXTRA_DIST = run > diff --git a/tests/ust/nprocesses/Makefile.am b/tests/ust/nprocesses/Makefile.am > index 20beea0..bc3a503 100644 > --- a/tests/ust/nprocesses/Makefile.am > +++ b/tests/ust/nprocesses/Makefile.am > @@ -10,7 +10,7 @@ endif > > noinst_PROGRAMS = gen-events-time > gen_events_time_SOURCES = gen-events-time.c tp.c ust_gen_event.h > -gen_events_time_LDADD = -llttng-ust > +gen_events_time_LDADD = -llttng-ust -lurcu-bp > > noinst_SCRIPTS = run > EXTRA_DIST = run From jbernard at debian.org Wed Nov 28 16:08:45 2012 From: jbernard at debian.org (Jon Bernard) Date: Wed, 28 Nov 2012 16:08:45 -0500 Subject: [lttng-dev] [PATCH lttng-tools] Link test utilities against urcu-bp In-Reply-To: <50B64AB6.6080904@efficios.com> References: <20121128151359.GA2051@quintessa> <50B64AB6.6080904@efficios.com> Message-ID: <20121128210845.GA30284@quintessa> * David Goulet wrote: > Hi Jon, > > Can you enlighten us on what setup are you using? > > This symbol is used by lttng-ust which is linked with -lurcu-bp so > lttng-tools should not have an issue here. > > Are you cross-compiling ? Nothing unusual, I'm building lttng-tools (version 2.1.8~rc8) from source against URCU version 0.7.5 and UST version 2.1.0~rc2. During compilation (configure with no additional parameters), I see the following: make[3]: Entering directory `tests/tools/streaming' CC unit_tests.o CCLD unit_tests CC gen-ust-events.o CC tp.o CCLD gen-ust-events /usr/bin/ld: tp.o: undefined reference to symbol 'rcu_dereference_sym' This link error occurs on each of the gen-events targets as there is no explicit link against urcu-bp. I must have something different, as I'm sure you'd have noticed this earlier. What additional information might you need? Cheers -- Jon From Paul_Woegerer at mentor.com Thu Nov 29 04:11:05 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Thu, 29 Nov 2012 10:11:05 +0100 Subject: [lttng-dev] [PATCH lttng-modules] Update kernel probes to more detailed match to kernel versions In-Reply-To: <6C5EA58090A5ED459815C4D04C2B466F8C566A47@EU-MBX-01.mgc.mentorg.com> References: <1354096526-22098-1-git-send-email-andrew_gabbasov@mentor.com>, <20121128155032.GA9266@Krystal> <6C5EA58090A5ED459815C4D04C2B466F8C566A47@EU-MBX-01.mgc.mentorg.com> Message-ID: <50B726A9.7010008@mentor.com> On 11/28/2012 06:16 PM, Gabbasov, Andrew wrote: >>> The code was verified to compile with latest versions in all stable >>> branches from 2.6.38.x to 3.6.x and 3.7-rc7. >> >> I get this build failure on 3.5 with this patch: >> >> CC [M] /home/compudj/work/lttng-modules/probes/lttng-probe-ext3.o >> /home/compudj/work/lttng-modules/probes/lttng-probe-ext3.c:30:29: fatal >> error: ../fs/ext3/ext3.h: No such file or directory >> compilation terminated. >> >> can you look into it and submit a revised patch ? > > You must be using kernel headers for building lttng-modules (linux-headers package > or something like that), right? This is what I was writing about: since ext3.h is not available > in kernel's "include" directory, and in order to avoid duplicating this file in lttng-modules > sources, we have to use that <../> based reference, and this requires having full kernel > source for building. The same issue will later be with btrfs and ext4 probes: their necessary > include files are also not available in kernel headers. I agree with Andrew. The problem is that some newer ftrace probes are written in a way that you have to have the full kernel source tree to build against them. For the ext3 probe I used a workaround and copied the included header from fs/ext3/ext3.h to instrumentation/events/mainline/fs_ext3.h to allow building without the full kernel source tree. But for the btrfs (and also the ext4) probe this will not work because they require even more headers that are not part of the kernel include dir. -- Paul -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. From Paul_Woegerer at mentor.com Thu Nov 29 04:21:42 2012 From: Paul_Woegerer at mentor.com (Woegerer, Paul) Date: Thu, 29 Nov 2012 10:21:42 +0100 Subject: [lttng-dev] "No space left on device" results in corrupt trace data set In-Reply-To: <50A661B4.10009@polymtl.ca> References: <50A655A1.6040804@mentor.com> <50A65BC4.3020708@efficios.com> <20121116153029.GB23798@Krystal> <50A65E22.3040203@mentor.com> <50A661B4.10009@polymtl.ca> Message-ID: <50B72926.9060900@mentor.com> On 11/16/2012 04:54 PM, Julien Desfossez wrote: >> Does that mean that the live tracing feature that currently lives in the >> lttngtop-live branch will go into lttng-tools and babeltrace any time soon ? > > The main change of lttng-tools 2.2 is the live tracing feature. > The way it is implemented in the lttngtop-live branch is more a > proof-of-concept, we will be starting the clean implementation > discussions here as soon as we have lttng-tools 2.1 released (which > should be around the end of this month). Hi Julien, I looked for "live tracing" related commits in the git repos but could find anything. There is also no RFC yet under: http://git.lttng.org/?p=lttng-tools.git;a=tree;f=doc/proposals;hb=HEAD Does development happen on some branch that I missed or did it simply not start yet. Thanks, Paul -- Paul Woegerer | SW Development Engineer http://go.mentor.com/sourceryanalyzer Mentor Embedded(tm) | Prinz Eugen Stra?e 72/2/4, Vienna, 1040 Austria Nucleus? | Linux? | Android(tm) | Services | UI | Multi-OS Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries.