Support for linux kernels 2.6.32 through 2.6.37
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 2 Sep 2012 19:33:09 +0000 (12:33 -0700)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Sun, 2 Sep 2012 19:33:09 +0000 (12:33 -0700)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
22 files changed:
.gitignore
Makefile
README
instrumentation/events/lttng-module/irq.h
instrumentation/events/lttng-module/sched.h
instrumentation/events/lttng-module/timer.h
linux-patches/backport-kallsym-sym-2.6.32.patch [new file with mode: 0644]
linux-patches/backport-splice-sym-2.6.32-34.patch [new file with mode: 0644]
linux-patches/backport-tp-2.6.34-tracepoint-data.patch [new file with mode: 0644]
linux-patches/backport-tracepoint-data-2.6.32-33.patch [new file with mode: 0644]
lttng-events.c
lttng-events.h
lttng-statedump-impl.c
lttng-syscalls.c
probes/Makefile
probes/define_trace.h
probes/lttng-probe-irq.c
probes/lttng-probe-sched.c
probes/lttng-probe-timer.c
wrapper/perf.h
wrapper/spinlock.h
wrapper/tracepoint.h [new file with mode: 0644]

index 8faa6c02b39ec3896bd4e989c82ce7f6dbdaf04a..7a1e643c673b0c6a53ebe57c82a37d2c85145e05 100644 (file)
@@ -29,7 +29,6 @@ modules.builtin
 *.bz2
 *.lzma
 *.lzo
-*.patch
 *.gcno
 
 #
index d4b09bbeac5cbe0ab65c1a0d9d00e1c597fae3a8..4cc8b6bf429a47288adef4c69707c337cc4d97a0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,7 @@ endif
 ifneq ($(CONFIG_PERF_EVENTS),)
 lttng-tracer-objs += $(shell \
        if [ $(VERSION) -ge 3 \
-               -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 33 \) ] ; then \
+               -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 34 \) ] ; then \
                echo "lttng-context-perf-counters.o" ; fi;)
 endif
 
diff --git a/README b/README
index 30f13386b9876bfde603e805bb0352bc33f2b3ba..1bcd5b2d69bd9109bdb38236063470294b3f3d7d 100644 (file)
--- a/README
+++ b/README
@@ -38,15 +38,16 @@ http://lttng.org/lttng2.0
 
 So far, it has been tested on vanilla Linux kernels 2.6.38, 2.6.39, 3.0,
 3.1, 3.2, 3.3 (on x86 32/64-bit, and powerpc 32-bit at the moment, build
-tested on ARM). It should work fine with newer kernels and other
-architectures, but expect build issues with kernels older than 2.6.36.
-The clock source currently used is the standard gettimeofday (slower,
-less scalable and less precise than the LTTng 0.x clocks).  Support for
-LTTng 0.x clocks will be added back soon into LTTng 2.0.  Please note
-that lttng-modules 2.0 can build on a Linux kernel patched with the
-LTTng 0.x patchset, but the lttng-modules 2.0 replace the lttng-modules
-0.x, so both tracers cannot be installed at the same time for a given
-kernel version.
+tested on ARM). Kernels 2.6.32 to 2.6.34 need up to 3 patches applied
+(refer to linux-patches within the lttng-modules tree). It should work
+fine with newer kernels and other architectures, but expect build issues
+with kernels older than 2.6.36.  The clock source currently used is the
+standard gettimeofday (slower, less scalable and less precise than the
+LTTng 0.x clocks).  Support for LTTng 0.x clocks will be added back soon
+into LTTng 2.0.  Please note that lttng-modules 2.0 can build on a Linux
+kernel patched with the LTTng 0.x patchset, but the lttng-modules 2.0
+replace the lttng-modules 0.x, so both tracers cannot be installed at
+the same time for a given kernel version.
 
 
 * Kernel config options required
index 344015d4654a471bb2d187fade10bca30dba1f8d..e766326d214205f08b8b3af5d556e47265bc074a 100644 (file)
@@ -89,6 +89,7 @@ TRACE_EVENT(irq_handler_exit,
                  __entry->irq, __entry->ret ? "handled" : "unhandled")
 )
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
 DECLARE_EVENT_CLASS(softirq,
 
        TP_PROTO(unsigned int vec_nr),
@@ -148,6 +149,70 @@ DEFINE_EVENT(softirq, softirq_raise,
 
        TP_ARGS(vec_nr)
 )
+#else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) */
+DECLARE_EVENT_CLASS(softirq,
+
+       TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+       TP_ARGS(h, vec),
+
+       TP_STRUCT__entry(
+               __field(        unsigned int,   vec     )
+       ),
+
+       TP_fast_assign(
+               tp_assign(vec, (int)(h - vec))
+       ),
+
+       TP_printk("vec=%u [action=%s]", __entry->vec,
+                 show_softirq_name(__entry->vec))
+)
+
+/**
+ * softirq_entry - called immediately before the softirq handler
+ * @h: pointer to struct softirq_action
+ * @vec: pointer to first struct softirq_action in softirq_vec array
+ *
+ * When used in combination with the softirq_exit tracepoint
+ * we can determine the softirq handler runtine.
+ */
+DEFINE_EVENT(softirq, softirq_entry,
+
+       TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+       TP_ARGS(h, vec)
+)
+
+/**
+ * softirq_exit - called immediately after the softirq handler returns
+ * @h: pointer to struct softirq_action
+ * @vec: pointer to first struct softirq_action in softirq_vec array
+ *
+ * When used in combination with the softirq_entry tracepoint
+ * we can determine the softirq handler runtine.
+ */
+DEFINE_EVENT(softirq, softirq_exit,
+
+       TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+       TP_ARGS(h, vec)
+)
+
+/**
+ * softirq_raise - called immediately when a softirq is raised
+ * @h: pointer to struct softirq_action
+ * @vec: pointer to first struct softirq_action in softirq_vec array
+ *
+ * When used in combination with the softirq_entry tracepoint
+ * we can determine the softirq raise to run latency.
+ */
+DEFINE_EVENT(softirq, softirq_raise,
+
+       TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+
+       TP_ARGS(h, vec)
+)
+#endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) */
 
 #endif /*  _TRACE_IRQ_H */
 
index 33f69213e4245f4da29ddfe0f105fd81482db629..b68616e068111af4b67aa46ac91ef2fae4615ec9 100644 (file)
@@ -74,9 +74,15 @@ TRACE_EVENT(sched_kthread_stop_ret,
  */
 DECLARE_EVENT_CLASS(sched_wakeup_template,
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
        TP_PROTO(struct task_struct *p, int success),
 
        TP_ARGS(p, success),
+#else
+       TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+
+       TP_ARGS(rq, p, success),
+#endif
 
        TP_STRUCT__entry(
                __array_text(   char,   comm,   TASK_COMM_LEN   )
@@ -99,6 +105,8 @@ DECLARE_EVENT_CLASS(sched_wakeup_template,
                  __entry->success, __entry->target_cpu)
 )
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
+
 DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
             TP_PROTO(struct task_struct *p, int success),
             TP_ARGS(p, success))
@@ -110,15 +118,37 @@ DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
             TP_PROTO(struct task_struct *p, int success),
             TP_ARGS(p, success))
 
+#else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) */
+
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup,
+            TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+            TP_ARGS(rq, p, success))
+
+/*
+ * Tracepoint for waking up a new task:
+ */
+DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new,
+            TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+            TP_ARGS(rq, p, success))
+
+#endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) */
+
 /*
  * Tracepoint for task switches, performed by the scheduler:
  */
 TRACE_EVENT(sched_switch,
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
        TP_PROTO(struct task_struct *prev,
                 struct task_struct *next),
 
        TP_ARGS(prev, next),
+#else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) */
+       TP_PROTO(struct rq *rq, struct task_struct *prev,
+                struct task_struct *next),
+
+       TP_ARGS(rq, prev, next),
+#endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) */
 
        TP_STRUCT__entry(
                __array_text(   char,   prev_comm,      TASK_COMM_LEN   )
@@ -220,9 +250,15 @@ DEFINE_EVENT(sched_process_template, sched_process_exit,
 /*
  * Tracepoint for waiting on task to unschedule:
  */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
 DEFINE_EVENT(sched_process_template, sched_wait_task,
        TP_PROTO(struct task_struct *p),
        TP_ARGS(p))
+#else /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) */
+DEFINE_EVENT(sched_process_template, sched_wait_task,
+       TP_PROTO(struct rq *rq, struct task_struct *p),
+       TP_ARGS(rq, p))
+#endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) */
 
 /*
  * Tracepoint for a waiting task:
index fa89f663abe4de13663f05feb6dc753f609a5e6d..dd27838e96efd68a90ccf9d014ac50dd2a53d5f8 100644 (file)
@@ -10,6 +10,9 @@
 #define _TRACE_TIMER_DEF_
 #include <linux/hrtimer.h>
 #include <linux/timer.h>
+
+struct timer_list;
+
 #endif /* _TRACE_TIMER_DEF_ */
 
 DECLARE_EVENT_CLASS(timer_class,
diff --git a/linux-patches/backport-kallsym-sym-2.6.32.patch b/linux-patches/backport-kallsym-sym-2.6.32.patch
new file mode 100644 (file)
index 0000000..2e72124
--- /dev/null
@@ -0,0 +1,37 @@
+commit e6b48d720e39d17f06a4462be4164e1a358817de
+Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date:   Sat Sep 1 17:51:33 2012 -0700
+
+    kallsyms: Re-enable export of kallsyms_lookup (backport)
+    
+    Backport of part of commit:
+    
+    commit f60d24d2ad04977b0bd9e3eb35dba2d2fa569af9
+    Author: Frederic Weisbecker <fweisbec@gmail.com>
+    Date:   Tue Nov 10 10:17:07 2009 +0100
+    
+        hw-breakpoints: Fix broken hw-breakpoint sample module
+    
+        The hw-breakpoint sample module has been broken during the
+        hw-breakpoint internals refactoring. Propagate the changes
+        to it.
+    
+        Reported-by: "K. Prasad" <prasad@linux.vnet.ibm.com>
+        Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
+    
+    for kernel 2.6.32.x. (just the symbol export)
+    
+    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
+index 8b6b8b6..8e5288a 100644
+--- a/kernel/kallsyms.c
++++ b/kernel/kallsyms.c
+@@ -181,6 +181,7 @@ unsigned long kallsyms_lookup_name(const char *name)
+       }
+       return module_kallsyms_lookup_name(name);
+ }
++EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
+ int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+                                     unsigned long),
diff --git a/linux-patches/backport-splice-sym-2.6.32-34.patch b/linux-patches/backport-splice-sym-2.6.32-34.patch
new file mode 100644 (file)
index 0000000..00be3b5
--- /dev/null
@@ -0,0 +1,71 @@
+commit f0d902f497ee2fb747086322a31925c7fb351d7a
+Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date:   Sat Sep 1 17:47:36 2012 -0700
+
+    mm: export generic_pipe_buf_*() to modules (backport)
+    
+    Backport for 2.6.32.x to 2.6.34.x of commits:
+    
+    commit 51921cb746f56983db5a373ca68deb2b0d3ddf01
+    Author: Miklos Szeredi <mszeredi@suse.cz>
+    Date:   Wed May 26 08:44:22 2010 +0200
+    
+        mm: export generic_pipe_buf_*() to modules
+    
+        This is needed by fuse device code which wants to create pipe buffers.
+        Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+    
+    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+diff --git a/fs/pipe.c b/fs/pipe.c
+index d0cc080..0eb6f53 100644
+--- a/fs/pipe.c
++++ b/fs/pipe.c
+@@ -222,6 +222,7 @@ void *generic_pipe_buf_map(struct pipe_inode_info *pipe,
+       return kmap(buf->page);
+ }
++EXPORT_SYMBOL(generic_pipe_buf_map);
+ /**
+  * generic_pipe_buf_unmap - unmap a previously mapped pipe buffer
+@@ -241,6 +242,7 @@ void generic_pipe_buf_unmap(struct pipe_inode_info *pipe,
+       } else
+               kunmap(buf->page);
+ }
++EXPORT_SYMBOL(generic_pipe_buf_unmap);
+ /**
+  * generic_pipe_buf_steal - attempt to take ownership of a &pipe_buffer
+@@ -271,6 +273,7 @@ int generic_pipe_buf_steal(struct pipe_inode_info *pipe,
+       return 1;
+ }
++EXPORT_SYMBOL(generic_pipe_buf_steal);
+ /**
+  * generic_pipe_buf_get - get a reference to a &struct pipe_buffer
+@@ -286,6 +289,7 @@ void generic_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
+ {
+       page_cache_get(buf->page);
+ }
++EXPORT_SYMBOL(generic_pipe_buf_get);
+ /**
+  * generic_pipe_buf_confirm - verify contents of the pipe buffer
+@@ -301,6 +305,7 @@ int generic_pipe_buf_confirm(struct pipe_inode_info *info,
+ {
+       return 0;
+ }
++EXPORT_SYMBOL(generic_pipe_buf_confirm);
+ /**
+  * generic_pipe_buf_release - put a reference to a &struct pipe_buffer
+@@ -315,6 +320,7 @@ void generic_pipe_buf_release(struct pipe_inode_info *pipe,
+ {
+       page_cache_release(buf->page);
+ }
++EXPORT_SYMBOL(generic_pipe_buf_release);
+ static const struct pipe_buf_operations anon_pipe_buf_ops = {
+       .can_merge = 1,
diff --git a/linux-patches/backport-tp-2.6.34-tracepoint-data.patch b/linux-patches/backport-tp-2.6.34-tracepoint-data.patch
new file mode 100644 (file)
index 0000000..385e87e
--- /dev/null
@@ -0,0 +1,545 @@
+commit 2c2a566b64b4254c530fb0c2222b30e8a739bac9
+Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date:   Sat Sep 1 17:45:09 2012 -0700
+
+    tracing: Let tracepoints have data passed to tracepoint callbacks (backport)
+    
+    Backport of commit 38516ab59fbc5b3bb278cf5e1fe2867c70cff32e for
+    2.6.34.x. Keeping kABI compatibility.
+    
+    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+---
+ include/linux/tracepoint.h |  149 ++++++++++++++++++++++++++++++++++-----------
+ kernel/tracepoint.c        |  144 +++++++++++++++++++++++++++++++------------
+ 2 files changed, 219 insertions(+), 74 deletions(-)
+
+Index: linux/include/linux/tracepoint.h
+===================================================================
+--- linux.orig/include/linux/tracepoint.h
++++ linux/include/linux/tracepoint.h
+@@ -20,12 +20,20 @@
+ struct module;
+ struct tracepoint;
++#define HAVE_KABI_2635_TRACEPOINT
++
++struct tracepoint_func {
++      void *func;
++      void *data;
++      bool kabi_2635;
++};
++
+ struct tracepoint {
+       const char *name;               /* Tracepoint name */
+       int state;                      /* State. */
+       void (*regfunc)(void);
+       void (*unregfunc)(void);
+-      void **funcs;
++      struct tracepoint_func *funcs;
+ } __attribute__((aligned(32)));               /*
+                                        * Aligned on 32 bytes because it is
+                                        * globally visible and gcc happily
+@@ -43,17 +51,33 @@ struct tracepoint {
+ /*
+  * it_func[0] is never NULL because there is at least one element in the array
+  * when the array itself is non NULL.
+- */
+-#define __DO_TRACE(tp, proto, args)                                   \
+-      do {                                                            \
+-              void **it_func;                                         \
++ *
++ * Note, the proto and args passed in includes "__data" as the first parameter.
++ * The reason for this is to handle the "void" prototype. If a tracepoint
++ * has a "void" prototype, then it is invalid to declare a function
++ * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just
++ * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".
++  */
++#define __DO_TRACE(tp, data_proto, data_args, proto, args)            \
++      do {                                                            \
++              struct tracepoint_func *it_func_ptr;                    \
++              void *it_func;                                          \
++                                                                      \
++              rcu_read_lock_sched_notrace();                          \
++              it_func_ptr = rcu_dereference_sched((tp)->funcs);       \
++              if (it_func_ptr) {                                      \
++                      do {                                            \
++                              if (it_func_ptr->kabi_2635) {           \
++                                      void *__data;                   \
+                                                                       \
+-              rcu_read_lock_sched_notrace();                          \
+-              it_func = rcu_dereference_sched((tp)->funcs);           \
+-              if (it_func) {                                          \
+-                      do {                                            \
+-                              ((void(*)(proto))(*it_func))(args);     \
+-                      } while (*(++it_func));                         \
++                                      it_func = (it_func_ptr)->func;  \
++                                      __data = (it_func_ptr)->data;   \
++                                      ((void(*)(data_proto))(it_func))(data_args); \
++                              } else {                                \
++                                      it_func = (it_func_ptr)->func;  \
++                                      ((void(*)(proto))(it_func))(args); \
++                              }                                       \
++                      } while ((++it_func_ptr)->func);                \
+               }                                                       \
+               rcu_read_unlock_sched_notrace();                        \
+       } while (0)
+@@ -63,22 +87,39 @@ struct tracepoint {
+  * not add unwanted padding between the beginning of the section and the
+  * structure. Force alignment to the same alignment as the section start.
+  */
+-#define DECLARE_TRACE(name, proto, args)                              \
++#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)     \
+       extern struct tracepoint __tracepoint_##name;                   \
+       static inline void trace_##name(proto)                          \
+       {                                                               \
+               if (unlikely(__tracepoint_##name.state))                \
+                       __DO_TRACE(&__tracepoint_##name,                \
+-                              TP_PROTO(proto), TP_ARGS(args));        \
++                              TP_PROTO(data_proto),                   \
++                              TP_ARGS(data_args),                     \
++                              TP_PROTO(proto),                        \
++                              TP_ARGS(args));                         \
+       }                                                               \
+-      static inline int register_trace_##name(void (*probe)(proto))   \
+-      {                                                               \
++      static inline int                                               \
++      register_trace_##name(void (*probe)(proto))                     \
++      {                                                               \
+               return tracepoint_probe_register(#name, (void *)probe); \
+-      }                                                               \
+-      static inline int unregister_trace_##name(void (*probe)(proto)) \
+-      {                                                               \
+-              return tracepoint_probe_unregister(#name, (void *)probe);\
+-      }
++      }                                                               \
++      static inline int                                               \
++      unregister_trace_##name(void (*probe)(proto))                   \
++      {                                                               \
++              return tracepoint_probe_unregister(#name, (void *)probe); \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_register_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return kabi_2635_tracepoint_probe_register(#name, (void *)probe,        \
++                                               data);                 \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_unregister_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return kabi_2635_tracepoint_probe_unregister(#name, (void *)probe, \
++                                                 data);               \
++      }
+ #define DEFINE_TRACE_FN(name, reg, unreg)                             \
+@@ -100,19 +141,29 @@ extern void tracepoint_update_probe_rang
+       struct tracepoint *end);
+ #else /* !CONFIG_TRACEPOINTS */
+-#define DECLARE_TRACE(name, proto, args)                              \
+-      static inline void _do_trace_##name(struct tracepoint *tp, proto) \
+-      { }                                                             \
+-      static inline void trace_##name(proto)                          \
+-      { }                                                             \
+-      static inline int register_trace_##name(void (*probe)(proto))   \
+-      {                                                               \
+-              return -ENOSYS;                                         \
+-      }                                                               \
+-      static inline int unregister_trace_##name(void (*probe)(proto)) \
+-      {                                                               \
+-              return -ENOSYS;                                         \
+-      }
++#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)     \
++      static inline void trace_##name(proto)                          \
++      { }                                                             \
++      static inline int                                               \
++      register_trace_##name(void (*probe)(proto))                     \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }                                                               \
++      static inline int                                               \
++      unregister_trace_##name(void (*probe)(proto))                   \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_register_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_unregister_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }
+ #define DEFINE_TRACE_FN(name, reg, unreg)
+ #define DEFINE_TRACE(name)
+@@ -123,6 +174,28 @@ static inline void tracepoint_update_pro
+       struct tracepoint *end)
+ { }
+ #endif /* CONFIG_TRACEPOINTS */
++
++/*
++ * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
++ * (void). "void" is a special value in a function prototype and can
++ * not be combined with other arguments. Since the DECLARE_TRACE()
++ * macro adds a data element at the beginning of the prototype,
++ * we need a way to differentiate "(void *data, proto)" from
++ * "(void *data, void)". The second prototype is invalid.
++ *
++ * DECLARE_TRACE_NOARGS() passes "void" as the tracepoint prototype
++ * and "void *__data" as the callback prototype.
++ *
++ * DECLARE_TRACE() passes "proto" as the tracepoint protoype and
++ * "void *__data, proto" as the callback prototype.
++ */
++#define DECLARE_TRACE_NOARGS(name)                                    \
++      __DECLARE_TRACE(name, void, , void *__data, __data)
++#define DECLARE_TRACE(name, proto, args)                              \
++      __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
++                      PARAMS(void *__data, proto),                    \
++                      PARAMS(__data, args))
++
+ #endif /* DECLARE_TRACE */
+ /*
+@@ -130,15 +203,23 @@ static inline void tracepoint_update_pro
+  * Internal API, should not be used directly.
+  */
+ extern int tracepoint_probe_register(const char *name, void *probe);
++extern int kabi_2635_tracepoint_probe_register(const char *name, void *probe, void *data);
+ /*
+  * Disconnect a probe from a tracepoint.
+  * Internal API, should not be used directly.
+  */
+-extern int tracepoint_probe_unregister(const char *name, void *probe);
++extern int
++tracepoint_probe_unregister(const char *name, void *probe);
++extern int
++kabi_2635_tracepoint_probe_unregister(const char *name, void *probe, void *data);
+ extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
++extern int kabi_2635_tracepoint_probe_register_noupdate(const char *name, void *probe,
++                                            void *data);
+ extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
++extern int kabi_2635_tracepoint_probe_unregister_noupdate(const char *name, void *probe,
++                                              void *data);
+ extern void tracepoint_probe_update_all(void);
+ struct tracepoint_iter {
+Index: linux/kernel/tracepoint.c
+===================================================================
+--- linux.orig/kernel/tracepoint.c
++++ linux/kernel/tracepoint.c
+@@ -54,7 +54,7 @@ static struct hlist_head tracepoint_tabl
+  */
+ struct tracepoint_entry {
+       struct hlist_node hlist;
+-      void **funcs;
++      struct tracepoint_func *funcs;
+       int refcount;   /* Number of times armed. 0 if disarmed. */
+       char name[0];
+ };
+@@ -64,12 +64,12 @@ struct tp_probes {
+               struct rcu_head rcu;
+               struct list_head list;
+       } u;
+-      void *probes[0];
++      struct tracepoint_func probes[0];
+ };
+ static inline void *allocate_probes(int count)
+ {
+-      struct tp_probes *p  = kmalloc(count * sizeof(void *)
++      struct tp_probes *p  = kmalloc(count * sizeof(struct tracepoint_func)
+                       + sizeof(struct tp_probes), GFP_KERNEL);
+       return p == NULL ? NULL : p->probes;
+ }
+@@ -79,7 +79,7 @@ static void rcu_free_old_probes(struct r
+       kfree(container_of(head, struct tp_probes, u.rcu));
+ }
+-static inline void release_probes(void *old)
++static inline void release_probes(struct tracepoint_func *old)
+ {
+       if (old) {
+               struct tp_probes *tp_probes = container_of(old,
+@@ -95,15 +95,16 @@ static void debug_print_probes(struct tr
+       if (!tracepoint_debug || !entry->funcs)
+               return;
+-      for (i = 0; entry->funcs[i]; i++)
+-              printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]);
++      for (i = 0; entry->funcs[i].func; i++)
++              printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i].func);
+ }
+-static void *
+-tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
++static struct tracepoint_func *
++tracepoint_entry_add_probe(struct tracepoint_entry *entry,
++                         void *probe, void *data, bool kabi_2635)
+ {
+       int nr_probes = 0;
+-      void **old, **new;
++      struct tracepoint_func *old, *new;
+       WARN_ON(!probe);
+@@ -111,8 +112,9 @@ tracepoint_entry_add_probe(struct tracep
+       old = entry->funcs;
+       if (old) {
+               /* (N -> N+1), (N != 0, 1) probes */
+-              for (nr_probes = 0; old[nr_probes]; nr_probes++)
+-                      if (old[nr_probes] == probe)
++              for (nr_probes = 0; old[nr_probes].func; nr_probes++)
++                      if (old[nr_probes].func == probe &&
++                          old[nr_probes].data == data)
+                               return ERR_PTR(-EEXIST);
+       }
+       /* + 2 : one for new probe, one for NULL func */
+@@ -120,9 +122,11 @@ tracepoint_entry_add_probe(struct tracep
+       if (new == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (old)
+-              memcpy(new, old, nr_probes * sizeof(void *));
+-      new[nr_probes] = probe;
+-      new[nr_probes + 1] = NULL;
++              memcpy(new, old, nr_probes * sizeof(struct tracepoint_func));
++      new[nr_probes].func = probe;
++      new[nr_probes].data = data;
++      new[nr_probes].kabi_2635 = kabi_2635;
++      new[nr_probes + 1].func = NULL;
+       entry->refcount = nr_probes + 1;
+       entry->funcs = new;
+       debug_print_probes(entry);
+@@ -130,10 +134,11 @@ tracepoint_entry_add_probe(struct tracep
+ }
+ static void *
+-tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
++tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
++                            void *probe, void *data)
+ {
+       int nr_probes = 0, nr_del = 0, i;
+-      void **old, **new;
++      struct tracepoint_func *old, *new;
+       old = entry->funcs;
+@@ -142,8 +147,10 @@ tracepoint_entry_remove_probe(struct tra
+       debug_print_probes(entry);
+       /* (N -> M), (N > 1, M >= 0) probes */
+-      for (nr_probes = 0; old[nr_probes]; nr_probes++) {
+-              if ((!probe || old[nr_probes] == probe))
++      for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
++              if (!probe ||
++                  (old[nr_probes].func == probe &&
++                   old[nr_probes].data == data))
+                       nr_del++;
+       }
+@@ -160,10 +167,11 @@ tracepoint_entry_remove_probe(struct tra
+               new = allocate_probes(nr_probes - nr_del + 1);
+               if (new == NULL)
+                       return ERR_PTR(-ENOMEM);
+-              for (i = 0; old[i]; i++)
+-                      if ((probe && old[i] != probe))
++              for (i = 0; old[i].func; i++)
++                      if (probe &&
++                          (old[i].func != probe || old[i].data != data))
+                               new[j++] = old[i];
+-              new[nr_probes - nr_del] = NULL;
++              new[nr_probes - nr_del].func = NULL;
+               entry->refcount = nr_probes - nr_del;
+               entry->funcs = new;
+       }
+@@ -315,18 +323,19 @@ static void tracepoint_update_probes(voi
+       module_update_tracepoints();
+ }
+-static void *tracepoint_add_probe(const char *name, void *probe)
++static struct tracepoint_func *
++tracepoint_add_probe(const char *name, void *probe, void *data, bool kabi_2635)
+ {
+       struct tracepoint_entry *entry;
+-      void *old;
++      struct tracepoint_func *old;
+       entry = get_tracepoint(name);
+       if (!entry) {
+               entry = add_tracepoint(name);
+               if (IS_ERR(entry))
+-                      return entry;
++                      return (struct tracepoint_func *)entry;
+       }
+-      old = tracepoint_entry_add_probe(entry, probe);
++      old = tracepoint_entry_add_probe(entry, probe, data, kabi_2635);
+       if (IS_ERR(old) && !entry->refcount)
+               remove_tracepoint(entry);
+       return old;
+@@ -340,12 +349,14 @@ static void *tracepoint_add_probe(const
+  * Returns 0 if ok, error value on error.
+  * The probe address must at least be aligned on the architecture pointer size.
+  */
+-int tracepoint_probe_register(const char *name, void *probe)
++static
++int ___tracepoint_probe_register(const char *name, void *probe, void *data,
++                      bool kabi_2635)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_add_probe(name, probe);
++      old = tracepoint_add_probe(name, probe, data, kabi_2635);
+       mutex_unlock(&tracepoints_mutex);
+       if (IS_ERR(old))
+               return PTR_ERR(old);
+@@ -354,17 +365,30 @@ int tracepoint_probe_register(const char
+       release_probes(old);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_register(const char *name, void *probe, void *data)
++{
++      return ___tracepoint_probe_register(name, probe, data, 1);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_register);
++
++
++int tracepoint_probe_register(const char *name, void *probe)
++{
++      return ___tracepoint_probe_register(name, probe, NULL, 0);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_register);
+-static void *tracepoint_remove_probe(const char *name, void *probe)
++static struct tracepoint_func *
++tracepoint_remove_probe(const char *name, void *probe, void *data)
+ {
+       struct tracepoint_entry *entry;
+-      void *old;
++      struct tracepoint_func *old;
+       entry = get_tracepoint(name);
+       if (!entry)
+               return ERR_PTR(-ENOENT);
+-      old = tracepoint_entry_remove_probe(entry, probe);
++      old = tracepoint_entry_remove_probe(entry, probe, data);
+       if (IS_ERR(old))
+               return old;
+       if (!entry->refcount)
+@@ -382,12 +406,13 @@ static void *tracepoint_remove_probe(con
+  * itself uses stop_machine(), which insures that every preempt disabled section
+  * have finished.
+  */
+-int tracepoint_probe_unregister(const char *name, void *probe)
++static
++int ___tracepoint_probe_unregister(const char *name, void *probe, void *data)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_remove_probe(name, probe);
++      old = tracepoint_remove_probe(name, probe, data);
+       mutex_unlock(&tracepoints_mutex);
+       if (IS_ERR(old))
+               return PTR_ERR(old);
+@@ -396,6 +421,17 @@ int tracepoint_probe_unregister(const ch
+       release_probes(old);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_unregister(const char *name, void *probe, void *data)
++{
++      return ___tracepoint_probe_unregister(name, probe, data);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_unregister);
++
++int tracepoint_probe_unregister(const char *name, void *probe)
++{
++      return ___tracepoint_probe_unregister(name, probe, NULL);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
+ static LIST_HEAD(old_probes);
+@@ -418,12 +454,14 @@ static void tracepoint_add_old_probes(vo
+  *
+  * caller must call tracepoint_probe_update_all()
+  */
+-int tracepoint_probe_register_noupdate(const char *name, void *probe)
++static
++int ___tracepoint_probe_register_noupdate(const char *name, void *probe,
++                                     void *data, bool kabi_2635)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_add_probe(name, probe);
++      old = tracepoint_add_probe(name, probe, data, kabi_2635);
+       if (IS_ERR(old)) {
+               mutex_unlock(&tracepoints_mutex);
+               return PTR_ERR(old);
+@@ -432,6 +470,18 @@ int tracepoint_probe_register_noupdate(c
+       mutex_unlock(&tracepoints_mutex);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_register_noupdate(const char *name, void *probe,
++                                     void *data)
++{
++      return ___tracepoint_probe_register_noupdate(name, probe, data, 1);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_register_noupdate);
++
++int tracepoint_probe_register_noupdate(const char *name, void *probe)
++{
++      return ___tracepoint_probe_register_noupdate(name, probe, NULL, 0);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
+ /**
+@@ -441,12 +491,14 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_regis
+  *
+  * caller must call tracepoint_probe_update_all()
+  */
+-int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
++static
++int ___tracepoint_probe_unregister_noupdate(const char *name, void *probe,
++                                       void *data)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_remove_probe(name, probe);
++      old = tracepoint_remove_probe(name, probe, data);
+       if (IS_ERR(old)) {
+               mutex_unlock(&tracepoints_mutex);
+               return PTR_ERR(old);
+@@ -455,6 +507,18 @@ int tracepoint_probe_unregister_noupdate
+       mutex_unlock(&tracepoints_mutex);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_unregister_noupdate(const char *name, void *probe,
++                                       void *data)
++{
++      return ___tracepoint_probe_unregister_noupdate(name, probe, data);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_unregister_noupdate);
++
++int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
++{
++      return ___tracepoint_probe_unregister_noupdate(name, probe, NULL);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
+ /**
diff --git a/linux-patches/backport-tracepoint-data-2.6.32-33.patch b/linux-patches/backport-tracepoint-data-2.6.32-33.patch
new file mode 100644 (file)
index 0000000..e344bac
--- /dev/null
@@ -0,0 +1,541 @@
+commit 2c2a566b64b4254c530fb0c2222b30e8a739bac9
+Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Date:   Sat Sep 1 17:45:09 2012 -0700
+
+    tracing: Let tracepoints have data passed to tracepoint callbacks (backport)
+    
+    Backport of commit 38516ab59fbc5b3bb278cf5e1fe2867c70cff32e for
+    2.6.32.x and 2.6.33.x. Keeping kABI compatibility.
+    
+    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+
+---
+ include/linux/tracepoint.h |  141 ++++++++++++++++++++++++++++++++++----------
+ kernel/tracepoint.c        |  144 ++++++++++++++++++++++++++++++++-------------
+ 2 files changed, 215 insertions(+), 70 deletions(-)
+
+Index: linux/include/linux/tracepoint.h
+===================================================================
+--- linux.orig/include/linux/tracepoint.h
++++ linux/include/linux/tracepoint.h
+@@ -20,12 +20,20 @@
+ struct module;
+ struct tracepoint;
++#define HAVE_KABI_2635_TRACEPOINT
++
++struct tracepoint_func {
++      void *func;
++      void *data;
++      bool kabi_2635;
++};
++
+ struct tracepoint {
+       const char *name;               /* Tracepoint name */
+       int state;                      /* State. */
+       void (*regfunc)(void);
+       void (*unregfunc)(void);
+-      void **funcs;
++      struct tracepoint_func *funcs;
+ } __attribute__((aligned(32)));               /*
+                                        * Aligned on 32 bytes because it is
+                                        * globally visible and gcc happily
+@@ -43,17 +51,33 @@ struct tracepoint {
+ /*
+  * it_func[0] is never NULL because there is at least one element in the array
+  * when the array itself is non NULL.
++ *
++ * Note, the proto and args passed in includes "__data" as the first parameter.
++ * The reason for this is to handle the "void" prototype. If a tracepoint
++ * has a "void" prototype, then it is invalid to declare a function
++ * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just
++ * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".
+  */
+-#define __DO_TRACE(tp, proto, args)                                   \
++#define __DO_TRACE(tp, data_proto, data_args, proto, args)            \
+       do {                                                            \
+-              void **it_func;                                         \
++              struct tracepoint_func *it_func_ptr;                    \
++              void *it_func;                                          \
+                                                                       \
+               rcu_read_lock_sched_notrace();                          \
+-              it_func = rcu_dereference((tp)->funcs);                 \
+-              if (it_func) {                                          \
++              it_func_ptr = rcu_dereference((tp)->funcs);             \
++              if (it_func_ptr) {                                      \
+                       do {                                            \
+-                              ((void(*)(proto))(*it_func))(args);     \
+-                      } while (*(++it_func));                         \
++                              if (it_func_ptr->kabi_2635) {           \
++                                      void *__data;                   \
++                                                                      \
++                                      it_func = (it_func_ptr)->func;  \
++                                      __data = (it_func_ptr)->data;   \
++                                      ((void(*)(data_proto))(it_func))(data_args); \
++                              } else {                                \
++                                      it_func = (it_func_ptr)->func;  \
++                                      ((void(*)(proto))(it_func))(args); \
++                              }                                       \
++                      } while ((++it_func_ptr)->func);                \
+               }                                                       \
+               rcu_read_unlock_sched_notrace();                        \
+       } while (0)
+@@ -63,22 +87,39 @@ struct tracepoint {
+  * not add unwanted padding between the beginning of the section and the
+  * structure. Force alignment to the same alignment as the section start.
+  */
+-#define DECLARE_TRACE(name, proto, args)                              \
++#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)     \
+       extern struct tracepoint __tracepoint_##name;                   \
+       static inline void trace_##name(proto)                          \
+       {                                                               \
+               if (unlikely(__tracepoint_##name.state))                \
+                       __DO_TRACE(&__tracepoint_##name,                \
+-                              TP_PROTO(proto), TP_ARGS(args));        \
++                              TP_PROTO(data_proto),                   \
++                              TP_ARGS(data_args),                     \
++                              TP_PROTO(proto),                        \
++                              TP_ARGS(args));                         \
+       }                                                               \
+-      static inline int register_trace_##name(void (*probe)(proto))   \
+-      {                                                               \
++      static inline int                                               \
++      register_trace_##name(void (*probe)(proto))                     \
++      {                                                               \
+               return tracepoint_probe_register(#name, (void *)probe); \
+-      }                                                               \
+-      static inline int unregister_trace_##name(void (*probe)(proto)) \
+-      {                                                               \
+-              return tracepoint_probe_unregister(#name, (void *)probe);\
+-      }
++      }                                                               \
++      static inline int                                               \
++      unregister_trace_##name(void (*probe)(proto))                   \
++      {                                                               \
++              return tracepoint_probe_unregister(#name, (void *)probe); \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_register_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return kabi_2635_tracepoint_probe_register(#name, (void *)probe,        \
++                                               data);                 \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_unregister_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return kabi_2635_tracepoint_probe_unregister(#name, (void *)probe, \
++                                                 data);               \
++      }
+ #define DEFINE_TRACE_FN(name, reg, unreg)                             \
+@@ -100,19 +141,29 @@ extern void tracepoint_update_probe_rang
+       struct tracepoint *end);
+ #else /* !CONFIG_TRACEPOINTS */
+-#define DECLARE_TRACE(name, proto, args)                              \
+-      static inline void _do_trace_##name(struct tracepoint *tp, proto) \
+-      { }                                                             \
+-      static inline void trace_##name(proto)                          \
+-      { }                                                             \
+-      static inline int register_trace_##name(void (*probe)(proto))   \
+-      {                                                               \
+-              return -ENOSYS;                                         \
+-      }                                                               \
+-      static inline int unregister_trace_##name(void (*probe)(proto)) \
+-      {                                                               \
+-              return -ENOSYS;                                         \
+-      }
++#define __DECLARE_TRACE(name, proto, args, data_proto, data_args)     \
++      static inline void trace_##name(proto)                          \
++      { }                                                             \
++      static inline int                                               \
++      register_trace_##name(void (*probe)(proto))                     \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }                                                               \
++      static inline int                                               \
++      unregister_trace_##name(void (*probe)(proto))                   \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_register_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }                                                               \
++      static inline int                                               \
++      kabi_2635_unregister_trace_##name(void (*probe)(data_proto), void *data) \
++      {                                                               \
++              return -ENOSYS;                                         \
++      }
+ #define DEFINE_TRACE_FN(name, reg, unreg)
+ #define DEFINE_TRACE(name)
+@@ -123,6 +174,28 @@ static inline void tracepoint_update_pro
+       struct tracepoint *end)
+ { }
+ #endif /* CONFIG_TRACEPOINTS */
++
++/*
++ * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype
++ * (void). "void" is a special value in a function prototype and can
++ * not be combined with other arguments. Since the DECLARE_TRACE()
++ * macro adds a data element at the beginning of the prototype,
++ * we need a way to differentiate "(void *data, proto)" from
++ * "(void *data, void)". The second prototype is invalid.
++ *
++ * DECLARE_TRACE_NOARGS() passes "void" as the tracepoint prototype
++ * and "void *__data" as the callback prototype.
++ *
++ * DECLARE_TRACE() passes "proto" as the tracepoint protoype and
++ * "void *__data, proto" as the callback prototype.
++ */
++#define DECLARE_TRACE_NOARGS(name)                                    \
++      __DECLARE_TRACE(name, void, , void *__data, __data)
++#define DECLARE_TRACE(name, proto, args)                              \
++      __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
++                      PARAMS(void *__data, proto),                    \
++                      PARAMS(__data, args))
++
+ #endif /* DECLARE_TRACE */
+ /*
+@@ -130,15 +203,23 @@ static inline void tracepoint_update_pro
+  * Internal API, should not be used directly.
+  */
+ extern int tracepoint_probe_register(const char *name, void *probe);
++extern int kabi_2635_tracepoint_probe_register(const char *name, void *probe, void *data);
+ /*
+  * Disconnect a probe from a tracepoint.
+  * Internal API, should not be used directly.
+  */
+-extern int tracepoint_probe_unregister(const char *name, void *probe);
++extern int
++tracepoint_probe_unregister(const char *name, void *probe);
++extern int
++kabi_2635_tracepoint_probe_unregister(const char *name, void *probe, void *data);
+ extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
++extern int kabi_2635_tracepoint_probe_register_noupdate(const char *name, void *probe,
++                                            void *data);
+ extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
++extern int kabi_2635_tracepoint_probe_unregister_noupdate(const char *name, void *probe,
++                                              void *data);
+ extern void tracepoint_probe_update_all(void);
+ struct tracepoint_iter {
+Index: linux/kernel/tracepoint.c
+===================================================================
+--- linux.orig/kernel/tracepoint.c
++++ linux/kernel/tracepoint.c
+@@ -54,7 +54,7 @@ static struct hlist_head tracepoint_tabl
+  */
+ struct tracepoint_entry {
+       struct hlist_node hlist;
+-      void **funcs;
++      struct tracepoint_func *funcs;
+       int refcount;   /* Number of times armed. 0 if disarmed. */
+       char name[0];
+ };
+@@ -64,12 +64,12 @@ struct tp_probes {
+               struct rcu_head rcu;
+               struct list_head list;
+       } u;
+-      void *probes[0];
++      struct tracepoint_func probes[0];
+ };
+ static inline void *allocate_probes(int count)
+ {
+-      struct tp_probes *p  = kmalloc(count * sizeof(void *)
++      struct tp_probes *p  = kmalloc(count * sizeof(struct tracepoint_func)
+                       + sizeof(struct tp_probes), GFP_KERNEL);
+       return p == NULL ? NULL : p->probes;
+ }
+@@ -79,7 +79,7 @@ static void rcu_free_old_probes(struct r
+       kfree(container_of(head, struct tp_probes, u.rcu));
+ }
+-static inline void release_probes(void *old)
++static inline void release_probes(struct tracepoint_func *old)
+ {
+       if (old) {
+               struct tp_probes *tp_probes = container_of(old,
+@@ -95,15 +95,16 @@ static void debug_print_probes(struct tr
+       if (!tracepoint_debug || !entry->funcs)
+               return;
+-      for (i = 0; entry->funcs[i]; i++)
+-              printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]);
++      for (i = 0; entry->funcs[i].func; i++)
++              printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i].func);
+ }
+-static void *
+-tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
++static struct tracepoint_func *
++tracepoint_entry_add_probe(struct tracepoint_entry *entry,
++                         void *probe, void *data, bool kabi_2635)
+ {
+       int nr_probes = 0;
+-      void **old, **new;
++      struct tracepoint_func *old, *new;
+       WARN_ON(!probe);
+@@ -111,8 +112,9 @@ tracepoint_entry_add_probe(struct tracep
+       old = entry->funcs;
+       if (old) {
+               /* (N -> N+1), (N != 0, 1) probes */
+-              for (nr_probes = 0; old[nr_probes]; nr_probes++)
+-                      if (old[nr_probes] == probe)
++              for (nr_probes = 0; old[nr_probes].func; nr_probes++)
++                      if (old[nr_probes].func == probe &&
++                          old[nr_probes].data == data)
+                               return ERR_PTR(-EEXIST);
+       }
+       /* + 2 : one for new probe, one for NULL func */
+@@ -120,9 +122,11 @@ tracepoint_entry_add_probe(struct tracep
+       if (new == NULL)
+               return ERR_PTR(-ENOMEM);
+       if (old)
+-              memcpy(new, old, nr_probes * sizeof(void *));
+-      new[nr_probes] = probe;
+-      new[nr_probes + 1] = NULL;
++              memcpy(new, old, nr_probes * sizeof(struct tracepoint_func));
++      new[nr_probes].func = probe;
++      new[nr_probes].data = data;
++      new[nr_probes].kabi_2635 = kabi_2635;
++      new[nr_probes + 1].func = NULL;
+       entry->refcount = nr_probes + 1;
+       entry->funcs = new;
+       debug_print_probes(entry);
+@@ -130,10 +134,11 @@ tracepoint_entry_add_probe(struct tracep
+ }
+ static void *
+-tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
++tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
++                            void *probe, void *data)
+ {
+       int nr_probes = 0, nr_del = 0, i;
+-      void **old, **new;
++      struct tracepoint_func *old, *new;
+       old = entry->funcs;
+@@ -142,8 +147,10 @@ tracepoint_entry_remove_probe(struct tra
+       debug_print_probes(entry);
+       /* (N -> M), (N > 1, M >= 0) probes */
+-      for (nr_probes = 0; old[nr_probes]; nr_probes++) {
+-              if ((!probe || old[nr_probes] == probe))
++      for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
++              if (!probe ||
++                  (old[nr_probes].func == probe &&
++                   old[nr_probes].data == data))
+                       nr_del++;
+       }
+@@ -160,10 +167,11 @@ tracepoint_entry_remove_probe(struct tra
+               new = allocate_probes(nr_probes - nr_del + 1);
+               if (new == NULL)
+                       return ERR_PTR(-ENOMEM);
+-              for (i = 0; old[i]; i++)
+-                      if ((probe && old[i] != probe))
++              for (i = 0; old[i].func; i++)
++                      if (probe &&
++                          (old[i].func != probe || old[i].data != data))
+                               new[j++] = old[i];
+-              new[nr_probes - nr_del] = NULL;
++              new[nr_probes - nr_del].func = NULL;
+               entry->refcount = nr_probes - nr_del;
+               entry->funcs = new;
+       }
+@@ -315,18 +323,19 @@ static void tracepoint_update_probes(voi
+       module_update_tracepoints();
+ }
+-static void *tracepoint_add_probe(const char *name, void *probe)
++static struct tracepoint_func *
++tracepoint_add_probe(const char *name, void *probe, void *data, bool kabi_2635)
+ {
+       struct tracepoint_entry *entry;
+-      void *old;
++      struct tracepoint_func *old;
+       entry = get_tracepoint(name);
+       if (!entry) {
+               entry = add_tracepoint(name);
+               if (IS_ERR(entry))
+-                      return entry;
++                      return (struct tracepoint_func *)entry;
+       }
+-      old = tracepoint_entry_add_probe(entry, probe);
++      old = tracepoint_entry_add_probe(entry, probe, data, kabi_2635);
+       if (IS_ERR(old) && !entry->refcount)
+               remove_tracepoint(entry);
+       return old;
+@@ -340,12 +349,14 @@ static void *tracepoint_add_probe(const
+  * Returns 0 if ok, error value on error.
+  * The probe address must at least be aligned on the architecture pointer size.
+  */
+-int tracepoint_probe_register(const char *name, void *probe)
++static
++int ___tracepoint_probe_register(const char *name, void *probe, void *data,
++                      bool kabi_2635)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_add_probe(name, probe);
++      old = tracepoint_add_probe(name, probe, data, kabi_2635);
+       mutex_unlock(&tracepoints_mutex);
+       if (IS_ERR(old))
+               return PTR_ERR(old);
+@@ -354,17 +365,30 @@ int tracepoint_probe_register(const char
+       release_probes(old);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_register(const char *name, void *probe, void *data)
++{
++      return ___tracepoint_probe_register(name, probe, data, 1);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_register);
++
++
++int tracepoint_probe_register(const char *name, void *probe)
++{
++      return ___tracepoint_probe_register(name, probe, NULL, 0);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_register);
+-static void *tracepoint_remove_probe(const char *name, void *probe)
++static struct tracepoint_func *
++tracepoint_remove_probe(const char *name, void *probe, void *data)
+ {
+       struct tracepoint_entry *entry;
+-      void *old;
++      struct tracepoint_func *old;
+       entry = get_tracepoint(name);
+       if (!entry)
+               return ERR_PTR(-ENOENT);
+-      old = tracepoint_entry_remove_probe(entry, probe);
++      old = tracepoint_entry_remove_probe(entry, probe, data);
+       if (IS_ERR(old))
+               return old;
+       if (!entry->refcount)
+@@ -382,12 +406,13 @@ static void *tracepoint_remove_probe(con
+  * itself uses stop_machine(), which insures that every preempt disabled section
+  * have finished.
+  */
+-int tracepoint_probe_unregister(const char *name, void *probe)
++static
++int ___tracepoint_probe_unregister(const char *name, void *probe, void *data)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_remove_probe(name, probe);
++      old = tracepoint_remove_probe(name, probe, data);
+       mutex_unlock(&tracepoints_mutex);
+       if (IS_ERR(old))
+               return PTR_ERR(old);
+@@ -396,6 +421,17 @@ int tracepoint_probe_unregister(const ch
+       release_probes(old);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_unregister(const char *name, void *probe, void *data)
++{
++      return ___tracepoint_probe_unregister(name, probe, data);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_unregister);
++
++int tracepoint_probe_unregister(const char *name, void *probe)
++{
++      return ___tracepoint_probe_unregister(name, probe, NULL);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
+ static LIST_HEAD(old_probes);
+@@ -418,12 +454,14 @@ static void tracepoint_add_old_probes(vo
+  *
+  * caller must call tracepoint_probe_update_all()
+  */
+-int tracepoint_probe_register_noupdate(const char *name, void *probe)
++static
++int ___tracepoint_probe_register_noupdate(const char *name, void *probe,
++                                     void *data, bool kabi_2635)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_add_probe(name, probe);
++      old = tracepoint_add_probe(name, probe, data, kabi_2635);
+       if (IS_ERR(old)) {
+               mutex_unlock(&tracepoints_mutex);
+               return PTR_ERR(old);
+@@ -432,6 +470,18 @@ int tracepoint_probe_register_noupdate(c
+       mutex_unlock(&tracepoints_mutex);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_register_noupdate(const char *name, void *probe,
++                                     void *data)
++{
++      return ___tracepoint_probe_register_noupdate(name, probe, data, 1);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_register_noupdate);
++
++int tracepoint_probe_register_noupdate(const char *name, void *probe)
++{
++      return ___tracepoint_probe_register_noupdate(name, probe, NULL, 0);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
+ /**
+@@ -441,12 +491,14 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_regis
+  *
+  * caller must call tracepoint_probe_update_all()
+  */
+-int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
++static
++int ___tracepoint_probe_unregister_noupdate(const char *name, void *probe,
++                                       void *data)
+ {
+-      void *old;
++      struct tracepoint_func *old;
+       mutex_lock(&tracepoints_mutex);
+-      old = tracepoint_remove_probe(name, probe);
++      old = tracepoint_remove_probe(name, probe, data);
+       if (IS_ERR(old)) {
+               mutex_unlock(&tracepoints_mutex);
+               return PTR_ERR(old);
+@@ -455,6 +507,18 @@ int tracepoint_probe_unregister_noupdate
+       mutex_unlock(&tracepoints_mutex);
+       return 0;
+ }
++
++int kabi_2635_tracepoint_probe_unregister_noupdate(const char *name, void *probe,
++                                       void *data)
++{
++      return ___tracepoint_probe_unregister_noupdate(name, probe, data);
++}
++EXPORT_SYMBOL_GPL(kabi_2635_tracepoint_probe_unregister_noupdate);
++
++int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
++{
++      return ___tracepoint_probe_unregister_noupdate(name, probe, NULL);
++}
+ EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
+ /**
index 220178f71c96e565d64122e12fa856344e542b17..168c3b26b9d62d5195449550f06cc2fcdddd29a5 100644 (file)
@@ -30,6 +30,7 @@
 #include "wrapper/uuid.h"
 #include "wrapper/vmalloc.h"   /* for wrapper_vmalloc_sync_all() */
 #include "wrapper/random.h"
+#include "wrapper/tracepoint.h"
 #include "lttng-events.h"
 #include "lttng-tracer.h"
 
@@ -316,7 +317,7 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan,
                event->desc = lttng_event_get(event_param->name);
                if (!event->desc)
                        goto register_error;
-               ret = tracepoint_probe_register(event_param->name,
+               ret = kabi_2635_tracepoint_probe_register(event_param->name,
                                event->desc->probe_callback,
                                event);
                if (ret)
@@ -420,7 +421,7 @@ int _lttng_event_unregister(struct lttng_event *event)
 
        switch (event->instrumentation) {
        case LTTNG_KERNEL_TRACEPOINT:
-               ret = tracepoint_probe_unregister(event->desc->name,
+               ret = kabi_2635_tracepoint_probe_unregister(event->desc->name,
                                                  event->desc->probe_callback,
                                                  event);
                if (ret)
index be3979adceea520f4bfa5e98a4f975dd3053a36e..af5aa65be8fe0edcf0b519cca3466f9113583613 100644 (file)
@@ -23,6 +23,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <linux/version.h>
 #include <linux/list.h>
 #include <linux/kprobes.h>
 #include "wrapper/uuid.h"
@@ -320,7 +321,7 @@ void lttng_event_put(const struct lttng_event_desc *desc);
 int lttng_probes_init(void);
 void lttng_probes_exit(void);
 
-#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+#if defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
 int lttng_syscalls_register(struct lttng_channel *chan, void *filter);
 int lttng_syscalls_unregister(struct lttng_channel *chan);
 #else
index c92c331bee0a20be37ad5a985bc9ff970f9b75c0..be498acc437155223dd50bcc944cced350fa017e 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "lttng-events.h"
 #include "wrapper/irqdesc.h"
+#include "wrapper/spinlock.h"
 
 #ifdef CONFIG_GENERIC_HARDIRQS
 #include <linux/irq.h>
@@ -255,12 +256,12 @@ void lttng_list_interrupts(struct lttng_session *session)
                        irq_desc_get_chip(desc)->name ? : "unnamed_irq_chip";
 
                local_irq_save(flags);
-               raw_spin_lock(&desc->lock);
+               wrapper_desc_spin_lock(&desc->lock);
                for (action = desc->action; action; action = action->next) {
                        trace_lttng_statedump_interrupt(session,
                                irq, irq_chip_name, action);
                }
-               raw_spin_unlock(&desc->lock);
+               wrapper_desc_spin_unlock(&desc->lock);
                local_irq_restore(flags);
        }
 #undef irq_to_desc
index a1bc9d422a1fd1d23b67b96827c7dc5eaba8544b..62ed24aa66723c2cb16b8abe2a83cd6b5a8ccb48 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/ptrace.h>
 #include <asm/syscall.h>
 
+#include "wrapper/tracepoint.h"
 #include "lttng-events.h"
 
 #ifndef CONFIG_COMPAT
 static
 void syscall_entry_probe(void *__data, struct pt_regs *regs, long id);
 
+/*
+ * Forward declarations for old kernels.
+ */
+struct mmsghdr;
+struct rlimit64;
+struct oldold_utsname;
+struct old_utsname;
+struct sel_arg_struct;
+struct mmap_arg_struct;
+
 /*
  * Take care of NOARGS not supported by mainline.
  */
@@ -403,7 +414,7 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
        if (ret)
                return ret;
 #endif
-       ret = tracepoint_probe_register("sys_enter",
+       ret = kabi_2635_tracepoint_probe_register("sys_enter",
                        (void *) syscall_entry_probe, chan);
        if (ret)
                return ret;
@@ -411,11 +422,11 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter)
         * We change the name of sys_exit tracepoint due to namespace
         * conflict with sys_exit syscall entry.
         */
-       ret = tracepoint_probe_register("sys_exit",
+       ret = kabi_2635_tracepoint_probe_register("sys_exit",
                        (void *) __event_probe__exit_syscall,
                        chan->sc_exit);
        if (ret) {
-               WARN_ON_ONCE(tracepoint_probe_unregister("sys_enter",
+               WARN_ON_ONCE(kabi_2635_tracepoint_probe_unregister("sys_enter",
                        (void *) syscall_entry_probe, chan));
        }
        return ret;
@@ -430,12 +441,12 @@ int lttng_syscalls_unregister(struct lttng_channel *chan)
 
        if (!chan->sc_table)
                return 0;
-       ret = tracepoint_probe_unregister("sys_exit",
+       ret = kabi_2635_tracepoint_probe_unregister("sys_exit",
                        (void *) __event_probe__exit_syscall,
                        chan->sc_exit);
        if (ret)
                return ret;
-       ret = tracepoint_probe_unregister("sys_enter",
+       ret = kabi_2635_tracepoint_probe_unregister("sys_enter",
                        (void *) syscall_entry_probe, chan);
        if (ret)
                return ret;
index 698a9c9c3674dc0005a18a26e10b09411e3953a7..6efd6ad1f240d7e2b4ce4a3b5acad22b6c2de128 100644 (file)
@@ -9,10 +9,8 @@ ccflags-y += -I$(PWD)/probes
 obj-m += lttng-types.o
 
 obj-m += lttng-probe-lttng.o
-
 obj-m += lttng-probe-sched.o
 obj-m += lttng-probe-irq.o
-obj-m += lttng-probe-signal.o
 obj-m += lttng-probe-timer.o
 
 obj-m += lttng-probe-statedump.o
@@ -21,6 +19,11 @@ ifneq ($(CONFIG_KVM),)
 obj-m += lttng-probe-kvm.o
 endif
 
+obj-m +=  $(shell \
+       if [ $(VERSION) -ge 3 \
+               -o \( $(VERSION) -eq 2 -a $(PATCHLEVEL) -ge 6 -a $(SUBLEVEL) -ge 35 \) ] ; then \
+               echo "lttng-probe-signal.o" ; fi;)
+
 ifneq ($(CONFIG_BLOCK),)
 ifneq ($(CONFIG_EVENT_TRACING),)       # need blk_cmd_buf_len
 obj-m +=  $(shell \
index e90310313932353f5a8f5729d2ceb0a2aee463bd..a518390b334bff6e20a912c9077c0aac6abddad6 100644 (file)
 #undef DEFINE_EVENT_PRINT
 #undef DEFINE_EVENT_CONDITION
 #undef TRACE_HEADER_MULTI_READ
-#undef DECLARE_TRACE
 
 /* Only undef what we defined in this file */
 #ifdef UNDEF_TRACE_INCLUDE_FILE
index 8f5bcd20bc20c86ee57148ae7ea99bbba69dcf5d..afcd1d215d0393e19a8cc0c3a1ce9227e2784cc9 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include "../wrapper/tracepoint.h"
 
 /*
  * Create the tracepoint static inlines from the kernel to validate that our
index 9b3ca5d69de834af2c46bc1a9e632fafa06aa5ad..caef6f70f951b88224ceb7c416698f98d674b12b 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/module.h>
+#include "../wrapper/tracepoint.h"
 
 /*
  * Create the tracepoint static inlines from the kernel to validate that our
index 3368bd80c56abd4c9b72dcd736590b3083d8323b..9cf7492a76555cbca8b43edd1e3d1383e79dabe6 100644 (file)
  */
 
 #include <linux/module.h>
+#include "../wrapper/tracepoint.h"
 
 /*
  * Create the tracepoint static inlines from the kernel to validate that our
  * trace event macros match the kernel we run on.
  */
+
 #include <linux/sched.h>
 #include <trace/events/timer.h>
 
index 2caf308ab0abc6711070e0f796e337db1c607852..5dfa84b388ec2262030de819b208f5f83c9de065 100644 (file)
@@ -32,7 +32,9 @@ wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr,
 {
        return perf_event_create_kernel_counter(attr, cpu, task, callback, NULL);
 }
-#else
+#else /* defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,99)) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
 static inline struct perf_event *
 wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr,
                                int cpu,
@@ -41,6 +43,26 @@ wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr,
 {
        return perf_event_create_kernel_counter(attr, cpu, task, callback);
 }
-#endif
+#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) */
+static inline struct perf_event *
+wrapper_perf_event_create_kernel_counter(struct perf_event_attr *attr,
+                               int cpu,
+                               struct task_struct *task,
+                               perf_overflow_handler_t callback)
+{
+       pid_t pid;
+
+       if (!task)
+               pid = -1;
+       else
+               pid = task->pid;
+
+       return perf_event_create_kernel_counter(attr, cpu, pid, callback);
+}
+
+#define local64_read(l)                atomic64_read(l)
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) */
+
+#endif /* defined(CONFIG_PERF_EVENTS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,99)) */
 
 #endif /* _LTTNG_WRAPPER_PERF_H */
index fdeb91a4d1c58f7289b677cccef9cb44ed2b5a59..bc71b4f4b0df8320c43f4f8c79e3f81489130639 100644 (file)
 
 #define raw_spin_is_locked(lock)       __raw_spin_is_locked(lock)
 
+#define wrapper_desc_spin_lock(lock)   spin_lock(lock)
+#define wrapper_desc_spin_unlock(lock) spin_unlock(lock)
+
+#else
+
+#define wrapper_desc_spin_lock(lock)   raw_spin_lock(lock)
+#define wrapper_desc_spin_unlock(lock) raw_spin_unlock(lock)
 
 #endif
 #endif /* _LTTNG_WRAPPER_SPINLOCK_H */
diff --git a/wrapper/tracepoint.h b/wrapper/tracepoint.h
new file mode 100644 (file)
index 0000000..798d785
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _LTTNG_WRAPPER_TRACEPOINT_H
+#define _LTTNG_WRAPPER_TRACEPOINT_H
+
+/*
+ * wrapper/tracepoint.h
+ *
+ * wrapper around DECLARE_EVENT_CLASS.
+ *
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/version.h>
+#include <linux/tracepoint.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+
+#define DECLARE_EVENT_CLASS(name, proto, args, tstruct, assign, print)
+
+#endif
+
+#ifndef HAVE_KABI_2635_TRACEPOINT
+
+#define kabi_2635_tracepoint_probe_register tracepoint_probe_register
+#define kabi_2635_tracepoint_probe_unregister tracepoint_probe_unregister
+#define kabi_2635_tracepoint_probe_register_noupdate tracepoint_probe_register_noupdate
+#define kabi_2635_tracepoint_probe_unregister_noupdate tracepoint_probe_unregister_noupdate
+
+#endif /* HAVE_KABI_2635_TRACEPOINT */
+
+#endif /* _LTTNG_WRAPPER_TRACEPOINT_H */
This page took 0.049039 seconds and 4 git commands to generate.