Skip to content

Commit

Permalink
tracepoints: add DECLARE_TRACE() and DEFINE_TRACE()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mathieu Desnoyers authored and Ingo Molnar committed Nov 16, 2008
1 parent 32f8574 commit 7e066fb
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 25 deletions.
7 changes: 6 additions & 1 deletion Documentation/tracepoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ In include/trace/subsys.h :

#include <linux/tracepoint.h>

DEFINE_TRACE(subsys_eventname,
DECLARE_TRACE(subsys_eventname,
TPPTOTO(int firstarg, struct task_struct *p),
TPARGS(firstarg, p));

In subsys/file.c (where the tracing statement must be added) :

#include <trace/subsys.h>

DEFINE_TRACE(subsys_eventname);

void somefct(void)
{
...
Expand Down Expand Up @@ -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
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

Expand Down
1 change: 1 addition & 0 deletions include/asm-generic/vmlinux.lds.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
VMLINUX_SYMBOL(__start___markers) = .; \
*(__markers) \
VMLINUX_SYMBOL(__stop___markers) = .; \
. = ALIGN(32); \
VMLINUX_SYMBOL(__start___tracepoints) = .; \
*(__tracepoints) \
VMLINUX_SYMBOL(__stop___tracepoints) = .; \
Expand Down
35 changes: 25 additions & 10 deletions include/linux/tracepoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ struct tracepoint {
const char *name; /* Tracepoint name */
int state; /* State. */
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 TPARGS(args...) args
Expand Down Expand Up @@ -55,15 +59,10 @@ 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 DEFINE_TRACE(name, proto, args) \
#define DECLARE_TRACE(name, proto, args) \
extern struct tracepoint __tracepoint_##name; \
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)) \
__DO_TRACE(&__tracepoint_##name, \
TPPROTO(proto), TPARGS(args)); \
Expand All @@ -77,11 +76,23 @@ struct tracepoint {
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,
struct tracepoint *end);

#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 trace_##name(proto) \
Expand All @@ -95,6 +106,10 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
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,
struct tracepoint *end)
{ }
Expand Down
24 changes: 12 additions & 12 deletions include/trace/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,52 @@
#include <linux/sched.h>
#include <linux/tracepoint.h>

DEFINE_TRACE(sched_kthread_stop,
DECLARE_TRACE(sched_kthread_stop,
TPPROTO(struct task_struct *t),
TPARGS(t));

DEFINE_TRACE(sched_kthread_stop_ret,
DECLARE_TRACE(sched_kthread_stop_ret,
TPPROTO(int ret),
TPARGS(ret));

DEFINE_TRACE(sched_wait_task,
DECLARE_TRACE(sched_wait_task,
TPPROTO(struct rq *rq, struct task_struct *p),
TPARGS(rq, p));

DEFINE_TRACE(sched_wakeup,
DECLARE_TRACE(sched_wakeup,
TPPROTO(struct rq *rq, struct task_struct *p),
TPARGS(rq, p));

DEFINE_TRACE(sched_wakeup_new,
DECLARE_TRACE(sched_wakeup_new,
TPPROTO(struct rq *rq, struct task_struct *p),
TPARGS(rq, p));

DEFINE_TRACE(sched_switch,
DECLARE_TRACE(sched_switch,
TPPROTO(struct rq *rq, struct task_struct *prev,
struct task_struct *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),
TPARGS(rq, p, dest_cpu));

DEFINE_TRACE(sched_process_free,
DECLARE_TRACE(sched_process_free,
TPPROTO(struct task_struct *p),
TPARGS(p));

DEFINE_TRACE(sched_process_exit,
DECLARE_TRACE(sched_process_exit,
TPPROTO(struct task_struct *p),
TPARGS(p));

DEFINE_TRACE(sched_process_wait,
DECLARE_TRACE(sched_process_wait,
TPPROTO(struct pid *pid),
TPARGS(pid));

DEFINE_TRACE(sched_process_fork,
DECLARE_TRACE(sched_process_fork,
TPPROTO(struct task_struct *parent, struct task_struct *child),
TPARGS(parent, child));

DEFINE_TRACE(sched_signal_send,
DECLARE_TRACE(sched_signal_send,
TPPROTO(int sig, struct task_struct *p),
TPARGS(sig, p));

Expand Down
4 changes: 4 additions & 0 deletions kernel/exit.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
#include <asm/pgtable.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 inline int task_detached(struct task_struct *p)
Expand Down
2 changes: 2 additions & 0 deletions kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ DEFINE_PER_CPU(unsigned long, process_counts) = 0;

__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */

DEFINE_TRACE(sched_process_fork);

int nr_processes(void)
{
int cpu;
Expand Down
3 changes: 3 additions & 0 deletions kernel/kthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ static DEFINE_SPINLOCK(kthread_create_lock);
static LIST_HEAD(kthread_create_list);
struct task_struct *kthreadd_task;

DEFINE_TRACE(sched_kthread_stop);
DEFINE_TRACE(sched_kthread_stop_ret);

struct kthread_create_info
{
/* Information passed to kthread() from kthreadd. */
Expand Down
6 changes: 6 additions & 0 deletions kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@
*/
#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
/*
* Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
Expand Down
2 changes: 2 additions & 0 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@

static struct kmem_cache *sigqueue_cachep;

DEFINE_TRACE(sched_signal_send);

static void __user *sig_handler(struct task_struct *t, int sig)
{
return t->sighand->action[sig - 1].sa.sa_handler;
Expand Down
4 changes: 2 additions & 2 deletions samples/tracepoints/tp-samples-trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
#include <linux/proc_fs.h> /* for struct inode and struct file */
#include <linux/tracepoint.h>

DEFINE_TRACE(subsys_event,
DECLARE_TRACE(subsys_event,
TPPROTO(struct inode *inode, struct file *file),
TPARGS(inode, file));
DEFINE_TRACE(subsys_eventb,
DECLARE_TRACE(subsys_eventb,
TPPROTO(void),
TPARGS());
#endif
3 changes: 3 additions & 0 deletions samples/tracepoints/tracepoint-sample.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include <linux/proc_fs.h>
#include "tp-samples-trace.h"

DEFINE_TRACE(subsys_event);
DEFINE_TRACE(subsys_eventb);

struct proc_dir_entry *pentry_example;

static int my_open(struct inode *inode, struct file *file)
Expand Down

0 comments on commit 7e066fb

Please sign in to comment.