tracepoints: add DECLARE_TRACE() and DEFINE_TRACE()
Impact: API *CHANGE*. Must update all tracepoint users. Add DEFINE_TRACE() to tracepoints to let them declare the tracepoint structure in a single spot for all the kernel. It helps reducing memory consumption, especially when declaring a lot of tracepoints, e.g. for kmalloc tracing. *API CHANGE WARNING*: now, DECLARE_TRACE() must be used in headers for tracepoint declarations rather than DEFINE_TRACE(). This is the sane way to do it. The name previously used was misleading. Updates scheduler instrumentation to follow this API change. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
32f8574277
commit
7e066fb870
|
@ -42,7 +42,7 @@ In include/trace/subsys.h :
|
||||||
|
|
||||||
#include <linux/tracepoint.h>
|
#include <linux/tracepoint.h>
|
||||||
|
|
||||||
DEFINE_TRACE(subsys_eventname,
|
DECLARE_TRACE(subsys_eventname,
|
||||||
TPPTOTO(int firstarg, struct task_struct *p),
|
TPPTOTO(int firstarg, struct task_struct *p),
|
||||||
TPARGS(firstarg, p));
|
TPARGS(firstarg, p));
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ In subsys/file.c (where the tracing statement must be added) :
|
||||||
|
|
||||||
#include <trace/subsys.h>
|
#include <trace/subsys.h>
|
||||||
|
|
||||||
|
DEFINE_TRACE(subsys_eventname);
|
||||||
|
|
||||||
void somefct(void)
|
void somefct(void)
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
|
@ -86,6 +88,9 @@ to limit collisions. Tracepoint names are global to the kernel: they are
|
||||||
considered as being the same whether they are in the core kernel image or in
|
considered as being the same whether they are in the core kernel image or in
|
||||||
modules.
|
modules.
|
||||||
|
|
||||||
|
If the tracepoint has to be used in kernel modules, an
|
||||||
|
EXPORT_TRACEPOINT_SYMBOL_GPL() or EXPORT_TRACEPOINT_SYMBOL() can be used to
|
||||||
|
export the defined tracepoints.
|
||||||
|
|
||||||
* Probe / tracepoint example
|
* Probe / tracepoint example
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
VMLINUX_SYMBOL(__start___markers) = .; \
|
VMLINUX_SYMBOL(__start___markers) = .; \
|
||||||
*(__markers) \
|
*(__markers) \
|
||||||
VMLINUX_SYMBOL(__stop___markers) = .; \
|
VMLINUX_SYMBOL(__stop___markers) = .; \
|
||||||
|
. = ALIGN(32); \
|
||||||
VMLINUX_SYMBOL(__start___tracepoints) = .; \
|
VMLINUX_SYMBOL(__start___tracepoints) = .; \
|
||||||
*(__tracepoints) \
|
*(__tracepoints) \
|
||||||
VMLINUX_SYMBOL(__stop___tracepoints) = .; \
|
VMLINUX_SYMBOL(__stop___tracepoints) = .; \
|
||||||
|
|
|
@ -24,8 +24,12 @@ struct tracepoint {
|
||||||
const char *name; /* Tracepoint name */
|
const char *name; /* Tracepoint name */
|
||||||
int state; /* State. */
|
int state; /* State. */
|
||||||
void **funcs;
|
void **funcs;
|
||||||
} __attribute__((aligned(8)));
|
} __attribute__((aligned(32))); /*
|
||||||
|
* Aligned on 32 bytes because it is
|
||||||
|
* globally visible and gcc happily
|
||||||
|
* align these on the structure size.
|
||||||
|
* Keep in sync with vmlinux.lds.h.
|
||||||
|
*/
|
||||||
|
|
||||||
#define TPPROTO(args...) args
|
#define TPPROTO(args...) args
|
||||||
#define TPARGS(args...) args
|
#define TPARGS(args...) args
|
||||||
|
@ -55,15 +59,10 @@ struct tracepoint {
|
||||||
* not add unwanted padding between the beginning of the section and the
|
* not add unwanted padding between the beginning of the section and the
|
||||||
* structure. Force alignment to the same alignment as the section start.
|
* structure. Force alignment to the same alignment as the section start.
|
||||||
*/
|
*/
|
||||||
#define DEFINE_TRACE(name, proto, args) \
|
#define DECLARE_TRACE(name, proto, args) \
|
||||||
|
extern struct tracepoint __tracepoint_##name; \
|
||||||
static inline void trace_##name(proto) \
|
static inline void trace_##name(proto) \
|
||||||
{ \
|
{ \
|
||||||
static const char __tpstrtab_##name[] \
|
|
||||||
__attribute__((section("__tracepoints_strings"))) \
|
|
||||||
= #name; \
|
|
||||||
static struct tracepoint __tracepoint_##name \
|
|
||||||
__attribute__((section("__tracepoints"), aligned(8))) = \
|
|
||||||
{ __tpstrtab_##name, 0, NULL }; \
|
|
||||||
if (unlikely(__tracepoint_##name.state)) \
|
if (unlikely(__tracepoint_##name.state)) \
|
||||||
__DO_TRACE(&__tracepoint_##name, \
|
__DO_TRACE(&__tracepoint_##name, \
|
||||||
TPPROTO(proto), TPARGS(args)); \
|
TPPROTO(proto), TPARGS(args)); \
|
||||||
|
@ -77,11 +76,23 @@ struct tracepoint {
|
||||||
return tracepoint_probe_unregister(#name, (void *)probe);\
|
return tracepoint_probe_unregister(#name, (void *)probe);\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFINE_TRACE(name) \
|
||||||
|
static const char __tpstrtab_##name[] \
|
||||||
|
__attribute__((section("__tracepoints_strings"))) = #name; \
|
||||||
|
struct tracepoint __tracepoint_##name \
|
||||||
|
__attribute__((section("__tracepoints"), aligned(32))) = \
|
||||||
|
{ __tpstrtab_##name, 0, NULL }
|
||||||
|
|
||||||
|
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
|
||||||
|
EXPORT_SYMBOL_GPL(__tracepoint_##name)
|
||||||
|
#define EXPORT_TRACEPOINT_SYMBOL(name) \
|
||||||
|
EXPORT_SYMBOL(__tracepoint_##name)
|
||||||
|
|
||||||
extern void tracepoint_update_probe_range(struct tracepoint *begin,
|
extern void tracepoint_update_probe_range(struct tracepoint *begin,
|
||||||
struct tracepoint *end);
|
struct tracepoint *end);
|
||||||
|
|
||||||
#else /* !CONFIG_TRACEPOINTS */
|
#else /* !CONFIG_TRACEPOINTS */
|
||||||
#define DEFINE_TRACE(name, proto, args) \
|
#define DECLARE_TRACE(name, proto, args) \
|
||||||
static inline void _do_trace_##name(struct tracepoint *tp, proto) \
|
static inline void _do_trace_##name(struct tracepoint *tp, proto) \
|
||||||
{ } \
|
{ } \
|
||||||
static inline void trace_##name(proto) \
|
static inline void trace_##name(proto) \
|
||||||
|
@ -95,6 +106,10 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
|
||||||
return -ENOSYS; \
|
return -ENOSYS; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEFINE_TRACE(name)
|
||||||
|
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
|
||||||
|
#define EXPORT_TRACEPOINT_SYMBOL(name)
|
||||||
|
|
||||||
static inline void tracepoint_update_probe_range(struct tracepoint *begin,
|
static inline void tracepoint_update_probe_range(struct tracepoint *begin,
|
||||||
struct tracepoint *end)
|
struct tracepoint *end)
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -4,52 +4,52 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/tracepoint.h>
|
#include <linux/tracepoint.h>
|
||||||
|
|
||||||
DEFINE_TRACE(sched_kthread_stop,
|
DECLARE_TRACE(sched_kthread_stop,
|
||||||
TPPROTO(struct task_struct *t),
|
TPPROTO(struct task_struct *t),
|
||||||
TPARGS(t));
|
TPARGS(t));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_kthread_stop_ret,
|
DECLARE_TRACE(sched_kthread_stop_ret,
|
||||||
TPPROTO(int ret),
|
TPPROTO(int ret),
|
||||||
TPARGS(ret));
|
TPARGS(ret));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_wait_task,
|
DECLARE_TRACE(sched_wait_task,
|
||||||
TPPROTO(struct rq *rq, struct task_struct *p),
|
TPPROTO(struct rq *rq, struct task_struct *p),
|
||||||
TPARGS(rq, p));
|
TPARGS(rq, p));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_wakeup,
|
DECLARE_TRACE(sched_wakeup,
|
||||||
TPPROTO(struct rq *rq, struct task_struct *p),
|
TPPROTO(struct rq *rq, struct task_struct *p),
|
||||||
TPARGS(rq, p));
|
TPARGS(rq, p));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_wakeup_new,
|
DECLARE_TRACE(sched_wakeup_new,
|
||||||
TPPROTO(struct rq *rq, struct task_struct *p),
|
TPPROTO(struct rq *rq, struct task_struct *p),
|
||||||
TPARGS(rq, p));
|
TPARGS(rq, p));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_switch,
|
DECLARE_TRACE(sched_switch,
|
||||||
TPPROTO(struct rq *rq, struct task_struct *prev,
|
TPPROTO(struct rq *rq, struct task_struct *prev,
|
||||||
struct task_struct *next),
|
struct task_struct *next),
|
||||||
TPARGS(rq, prev, next));
|
TPARGS(rq, prev, next));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_migrate_task,
|
DECLARE_TRACE(sched_migrate_task,
|
||||||
TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu),
|
TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu),
|
||||||
TPARGS(rq, p, dest_cpu));
|
TPARGS(rq, p, dest_cpu));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_process_free,
|
DECLARE_TRACE(sched_process_free,
|
||||||
TPPROTO(struct task_struct *p),
|
TPPROTO(struct task_struct *p),
|
||||||
TPARGS(p));
|
TPARGS(p));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_process_exit,
|
DECLARE_TRACE(sched_process_exit,
|
||||||
TPPROTO(struct task_struct *p),
|
TPPROTO(struct task_struct *p),
|
||||||
TPARGS(p));
|
TPARGS(p));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_process_wait,
|
DECLARE_TRACE(sched_process_wait,
|
||||||
TPPROTO(struct pid *pid),
|
TPPROTO(struct pid *pid),
|
||||||
TPARGS(pid));
|
TPARGS(pid));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_process_fork,
|
DECLARE_TRACE(sched_process_fork,
|
||||||
TPPROTO(struct task_struct *parent, struct task_struct *child),
|
TPPROTO(struct task_struct *parent, struct task_struct *child),
|
||||||
TPARGS(parent, child));
|
TPARGS(parent, child));
|
||||||
|
|
||||||
DEFINE_TRACE(sched_signal_send,
|
DECLARE_TRACE(sched_signal_send,
|
||||||
TPPROTO(int sig, struct task_struct *p),
|
TPPROTO(int sig, struct task_struct *p),
|
||||||
TPARGS(sig, p));
|
TPARGS(sig, p));
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,10 @@
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
|
|
||||||
|
DEFINE_TRACE(sched_process_free);
|
||||||
|
DEFINE_TRACE(sched_process_exit);
|
||||||
|
DEFINE_TRACE(sched_process_wait);
|
||||||
|
|
||||||
static void exit_mm(struct task_struct * tsk);
|
static void exit_mm(struct task_struct * tsk);
|
||||||
|
|
||||||
static inline int task_detached(struct task_struct *p)
|
static inline int task_detached(struct task_struct *p)
|
||||||
|
|
|
@ -79,6 +79,8 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0;
|
||||||
|
|
||||||
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
|
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
|
||||||
|
|
||||||
|
DEFINE_TRACE(sched_process_fork);
|
||||||
|
|
||||||
int nr_processes(void)
|
int nr_processes(void)
|
||||||
{
|
{
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
|
@ -21,6 +21,9 @@ static DEFINE_SPINLOCK(kthread_create_lock);
|
||||||
static LIST_HEAD(kthread_create_list);
|
static LIST_HEAD(kthread_create_list);
|
||||||
struct task_struct *kthreadd_task;
|
struct task_struct *kthreadd_task;
|
||||||
|
|
||||||
|
DEFINE_TRACE(sched_kthread_stop);
|
||||||
|
DEFINE_TRACE(sched_kthread_stop_ret);
|
||||||
|
|
||||||
struct kthread_create_info
|
struct kthread_create_info
|
||||||
{
|
{
|
||||||
/* Information passed to kthread() from kthreadd. */
|
/* Information passed to kthread() from kthreadd. */
|
||||||
|
|
|
@ -118,6 +118,12 @@
|
||||||
*/
|
*/
|
||||||
#define RUNTIME_INF ((u64)~0ULL)
|
#define RUNTIME_INF ((u64)~0ULL)
|
||||||
|
|
||||||
|
DEFINE_TRACE(sched_wait_task);
|
||||||
|
DEFINE_TRACE(sched_wakeup);
|
||||||
|
DEFINE_TRACE(sched_wakeup_new);
|
||||||
|
DEFINE_TRACE(sched_switch);
|
||||||
|
DEFINE_TRACE(sched_migrate_task);
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/*
|
/*
|
||||||
* Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
|
* Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
static struct kmem_cache *sigqueue_cachep;
|
static struct kmem_cache *sigqueue_cachep;
|
||||||
|
|
||||||
|
DEFINE_TRACE(sched_signal_send);
|
||||||
|
|
||||||
static void __user *sig_handler(struct task_struct *t, int sig)
|
static void __user *sig_handler(struct task_struct *t, int sig)
|
||||||
{
|
{
|
||||||
return t->sighand->action[sig - 1].sa.sa_handler;
|
return t->sighand->action[sig - 1].sa.sa_handler;
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
#include <linux/proc_fs.h> /* for struct inode and struct file */
|
#include <linux/proc_fs.h> /* for struct inode and struct file */
|
||||||
#include <linux/tracepoint.h>
|
#include <linux/tracepoint.h>
|
||||||
|
|
||||||
DEFINE_TRACE(subsys_event,
|
DECLARE_TRACE(subsys_event,
|
||||||
TPPROTO(struct inode *inode, struct file *file),
|
TPPROTO(struct inode *inode, struct file *file),
|
||||||
TPARGS(inode, file));
|
TPARGS(inode, file));
|
||||||
DEFINE_TRACE(subsys_eventb,
|
DECLARE_TRACE(subsys_eventb,
|
||||||
TPPROTO(void),
|
TPPROTO(void),
|
||||||
TPARGS());
|
TPARGS());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include "tp-samples-trace.h"
|
#include "tp-samples-trace.h"
|
||||||
|
|
||||||
|
DEFINE_TRACE(subsys_event);
|
||||||
|
DEFINE_TRACE(subsys_eventb);
|
||||||
|
|
||||||
struct proc_dir_entry *pentry_example;
|
struct proc_dir_entry *pentry_example;
|
||||||
|
|
||||||
static int my_open(struct inode *inode, struct file *file)
|
static int my_open(struct inode *inode, struct file *file)
|
||||||
|
|
Loading…
Reference in New Issue