linux/include/linux/tracepoint.h
<<
>>
Prefs
   1#ifndef _LINUX_TRACEPOINT_H
   2#define _LINUX_TRACEPOINT_H
   3
   4/*
   5 * Kernel Tracepoint API.
   6 *
   7 * See Documentation/tracepoint.txt.
   8 *
   9 * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
  10 *
  11 * Heavily inspired from the Linux Kernel Markers.
  12 *
  13 * This file is released under the GPLv2.
  14 * See the file COPYING for more details.
  15 */
  16
  17#include <linux/types.h>
  18#include <linux/rcupdate.h>
  19
  20struct module;
  21struct tracepoint;
  22
  23struct tracepoint {
  24        const char *name;               /* Tracepoint name */
  25        int state;                      /* State. */
  26        void **funcs;
  27} __attribute__((aligned(8)));
  28
  29
  30#define TPPROTO(args...)        args
  31#define TPARGS(args...)         args
  32
  33#ifdef CONFIG_TRACEPOINTS
  34
  35/*
  36 * it_func[0] is never NULL because there is at least one element in the array
  37 * when the array itself is non NULL.
  38 */
  39#define __DO_TRACE(tp, proto, args)                                     \
  40        do {                                                            \
  41                void **it_func;                                         \
  42                                                                        \
  43                rcu_read_lock_sched();                                  \
  44                it_func = rcu_dereference((tp)->funcs);                 \
  45                if (it_func) {                                          \
  46                        do {                                            \
  47                                ((void(*)(proto))(*it_func))(args);     \
  48                        } while (*(++it_func));                         \
  49                }                                                       \
  50                rcu_read_unlock_sched();                                \
  51        } while (0)
  52
  53/*
  54 * Make sure the alignment of the structure in the __tracepoints section will
  55 * not add unwanted padding between the beginning of the section and the
  56 * structure. Force alignment to the same alignment as the section start.
  57 */
  58#define DEFINE_TRACE(name, proto, args)                                 \
  59        static inline void trace_##name(proto)                          \
  60        {                                                               \
  61                static const char __tpstrtab_##name[]                   \
  62                __attribute__((section("__tracepoints_strings")))       \
  63                = #name ":" #proto;                                     \
  64                static struct tracepoint __tracepoint_##name            \
  65                __attribute__((section("__tracepoints"), aligned(8))) = \
  66                { __tpstrtab_##name, 0, NULL };                         \
  67                if (unlikely(__tracepoint_##name.state))                \
  68                        __DO_TRACE(&__tracepoint_##name,                \
  69                                TPPROTO(proto), TPARGS(args));          \
  70        }                                                               \
  71        static inline int register_trace_##name(void (*probe)(proto))   \
  72        {                                                               \
  73                return tracepoint_probe_register(#name ":" #proto,      \
  74                        (void *)probe);                                 \
  75        }                                                               \
  76        static inline void unregister_trace_##name(void (*probe)(proto))\
  77        {                                                               \
  78                tracepoint_probe_unregister(#name ":" #proto,           \
  79                        (void *)probe);                                 \
  80        }
  81
  82extern void tracepoint_update_probe_range(struct tracepoint *begin,
  83        struct tracepoint *end);
  84
  85#else /* !CONFIG_TRACEPOINTS */
  86#define DEFINE_TRACE(name, proto, args)                 \
  87        static inline void _do_trace_##name(struct tracepoint *tp, proto) \
  88        { }                                                             \
  89        static inline void trace_##name(proto)                          \
  90        { }                                                             \
  91        static inline int register_trace_##name(void (*probe)(proto))   \
  92        {                                                               \
  93                return -ENOSYS;                                         \
  94        }                                                               \
  95        static inline void unregister_trace_##name(void (*probe)(proto))\
  96        { }
  97
  98static inline void tracepoint_update_probe_range(struct tracepoint *begin,
  99        struct tracepoint *end)
 100{ }
 101#endif /* CONFIG_TRACEPOINTS */
 102
 103/*
 104 * Connect a probe to a tracepoint.
 105 * Internal API, should not be used directly.
 106 */
 107extern int tracepoint_probe_register(const char *name, void *probe);
 108
 109/*
 110 * Disconnect a probe from a tracepoint.
 111 * Internal API, should not be used directly.
 112 */
 113extern int tracepoint_probe_unregister(const char *name, void *probe);
 114
 115struct tracepoint_iter {
 116        struct module *module;
 117        struct tracepoint *tracepoint;
 118};
 119
 120extern void tracepoint_iter_start(struct tracepoint_iter *iter);
 121extern void tracepoint_iter_next(struct tracepoint_iter *iter);
 122extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
 123extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
 124extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
 125        struct tracepoint *begin, struct tracepoint *end);
 126
 127/*
 128 * tracepoint_synchronize_unregister must be called between the last tracepoint
 129 * probe unregistration and the end of module exit to make sure there is no
 130 * caller executing a probe when it is freed.
 131 */
 132static inline void tracepoint_synchronize_unregister(void)
 133{
 134        synchronize_sched();
 135}
 136
 137#endif
 138
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.