]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: record SDT and perf probe types in a new ELF section
authorNick Alcock <nick.alcock@oracle.com>
Wed, 14 Sep 2016 01:10:06 +0000 (02:10 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 28 Oct 2016 12:45:44 +0000 (13:45 +0100)
Before now, the types specified in the SDT probe macros in
include/linux/sdt.h were simply thrown away: DTrace was never
informed of them, and instead got type information for SDT probes
from a hardwired list in the out-of-tree sdt module.

As a start to fixing this, export the SDT type information into
a new ELF section named _dtrace_sdt_args.  Both native SDT probes
and perf probes translated into SDT probes use the same section:
its format is a sequence of probe type strings, with individual
arguments separated by commas, each type string separated from the
next by a NUL:

type string, comma-separated\0
...

(This is the same format used by perf probe prototype declarations,
and is what you'd get if you removed the argument names from a DTrace
SDT probe specification.)

The only difference between SDT and perf probe type strings is that the
type string for perf probes is also used to define a tracing function,
so it includes argument names.  The SDT format has various other
extensions which do not affect this commit so will be described later.

The type strings in the section are in no particular order (it depends on the
order in the source code) and may contain duplicates, so to associate
each string with a probe, there is another section, _dtrace_sdt_names,
which is a simple null-terminated array (string table) of names, associated
1:1 with the type strings in the _dtrace_sdt_types section.

At this point in the patch series, nothing uses the newly-added sections.

Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
Acked-by: Kris Van Hees <kris.van.hees@oracle.com>
Orabug: 24661801

include/asm-generic/vmlinux.lds.h
include/linux/sdt.h
include/linux/tracepoint.h

index 8bd374d3cf21fb0ee32e217f7f7eb6915c992514..1839145b44a2d8890f971340d539ae8f2500f79c 100644 (file)
 #define KPROBE_BLACKLIST()
 #endif
 
+#ifdef CONFIG_DTRACE
+#define DTRACE_SDT_NAMES()     . = ALIGN(8);                                   \
+                               VMLINUX_SYMBOL(__start_dtrace_sdt_names) = .;   \
+                               *(_dtrace_sdt_names)                            \
+                               VMLINUX_SYMBOL(__stop_dtrace_sdt_names) = .;
+#define DTRACE_SDT_ARGS()      . = ALIGN(8);                                   \
+                               VMLINUX_SYMBOL(__start_dtrace_sdt_args) = .;    \
+                               *(_dtrace_sdt_args)                             \
+                               VMLINUX_SYMBOL(__stop_dtrace_sdt_args) = .;
+#else
+#define DTRACE_SDT_NAMES()
+#define DTRACE_SDT_ARGS()
+#endif
+
 #ifdef CONFIG_EVENT_TRACING
 #define FTRACE_EVENTS()        . = ALIGN(8);                                   \
                        VMLINUX_SYMBOL(__start_ftrace_events) = .;      \
        FTRACE_EVENTS()                                                 \
        TRACE_SYSCALLS()                                                \
        KPROBE_BLACKLIST()                                              \
+       DTRACE_SDT_NAMES()                                              \
+       DTRACE_SDT_ARGS()                                               \
        MEM_DISCARD(init.rodata)                                        \
        CLK_OF_TABLES()                                                 \
        RESERVEDMEM_OF_TABLES()                                         \
index d659caf2f996b019e977b06c19585e5bedddcfdb..42ae116b21c68b4031a8f3a94f1550075338eac1 100644 (file)
@@ -57,6 +57,11 @@ extern "C" {
 
 #else /* __KERNEL__ */
 
+#include <linux/stringify.h>
+
+#define PROBENAME_STR(str) ".ascii \"" __stringify(str) "\"\n"
+#define ARG_STR(str) ".ascii \"" __stringify(str) ",\"\n"
+
 #define        DTRACE_PROBE(name)      {                                       \
        extern void __dtrace_probe_##name(void);                        \
        __dtrace_probe_##name();                                        \
@@ -65,17 +70,44 @@ extern "C" {
 #define        DTRACE_PROBE1(name, type1, arg1)        {                       \
        extern void __dtrace_probe_##name(uintptr_t);                   \
        __dtrace_probe_##name((uintptr_t)(arg1));                       \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE2(name, type1, arg1, type2, arg2)   {               \
        extern void __dtrace_probe_##name(uintptr_t, uintptr_t);        \
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2));    \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE3(name, type1, arg1, type2, arg2, type3, arg3) {    \
        extern void __dtrace_probe_##name(uintptr_t, uintptr_t, uintptr_t); \
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),     \
            (uintptr_t)(arg3));                                         \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ARG_STR(type3)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE4(name, type1, arg1, type2, arg2,                   \
@@ -84,6 +116,17 @@ extern "C" {
            uintptr_t, uintptr_t);                                      \
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),     \
            (uintptr_t)(arg3), (uintptr_t)(arg4));                      \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ARG_STR(type3)                                     \
+                    ARG_STR(type4)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE5(name, type1, arg1, type2, arg2,                   \
@@ -92,6 +135,18 @@ extern "C" {
            uintptr_t, uintptr_t, uintptr_t);                           \
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),     \
            (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5));   \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ARG_STR(type3)                                     \
+                    ARG_STR(type4)                                     \
+                    ARG_STR(type5)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE6(name, type1, arg1, type2, arg2,                   \
@@ -101,6 +156,19 @@ extern "C" {
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),     \
            (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5),    \
            (uintptr_t)(arg6));                                         \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ARG_STR(type3)                                     \
+                    ARG_STR(type4)                                     \
+                    ARG_STR(type5)                                     \
+                    ARG_STR(type6)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE7(name, type1, arg1, type2, arg2, type3, arg3,      \
@@ -110,6 +178,20 @@ extern "C" {
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),     \
            (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5),    \
            (uintptr_t)(arg6), (uintptr_t)(arg7));                      \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ARG_STR(type3)                                     \
+                    ARG_STR(type4)                                     \
+                    ARG_STR(type5)                                     \
+                    ARG_STR(type6)                                     \
+                    ARG_STR(type7)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #define        DTRACE_PROBE8(name, type1, arg1, type2, arg2, type3, arg3,      \
@@ -120,19 +202,40 @@ extern "C" {
        __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2),     \
            (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5),    \
            (uintptr_t)(arg6), (uintptr_t)(arg7), (uintptr_t)(arg8));   \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
+                    PROBENAME_STR(name)                                \
+                    ".byte 0\n"                                        \
+                    ".popsection\n"                                    \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
+                    ARG_STR(type1)                                     \
+                    ARG_STR(type2)                                     \
+                    ARG_STR(type3)                                     \
+                    ARG_STR(type4)                                     \
+                    ARG_STR(type5)                                     \
+                    ARG_STR(type6)                                     \
+                    ARG_STR(type7)                                     \
+                    ARG_STR(type8)                                     \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 
 #ifdef CONFIG_DT_SDT_PERF
 
-/* This counts the number of args */
+/*
+ * This counts the number of args.
+ */
 #define DTRACE_NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,N,...) N
 #define DTRACE_NARGS(...) DTRACE_NARGS_SEQ(__VA_ARGS__, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
 
-/* This will let macros expand before concating them */
+/*
+ * This will let macros expand before concatting them.
+ */
 #define DTRACE_PRIMITIVE_CAT(x, y) x ## y
 #define DTRACE_CAT(x, y) DTRACE_PRIMITIVE_CAT(x, y)
 
-/* This will call a macro on each argument passed in */
+/*
+ * This will call a macro on each argument passed in.
+ */
 #define DTRACE_APPLY(macro, ...) DTRACE_CAT(DTRACE_APPLY_, DTRACE_NARGS(__VA_ARGS__))(macro, __VA_ARGS__)
 #define DTRACE_APPLY_1(m, x1) m(x1)
 #define DTRACE_APPLY_2(m, x1, x2) m(x1), m(x2)
@@ -186,9 +289,19 @@ extern "C" {
        __dtrace_probe___perf_##name(DTRACE_APPLY(DTRACE_UINTPTR_CAST_EACH, args));     \
 }
 
+#define DTRACE_PROTO_TRACEPOINT(name, proto...) {                              \
+       asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n"       \
+                    ".ascii \"" __stringify(__perf_##name) "\"\n"              \
+                    ".byte 0\n"                                                \
+                    ".popsection\n"                                            \
+                    ".pushsection _dtrace_sdt_args, \"a\", @progbits\n"        \
+                    ".asciz \"" __stringify(proto) "\"\n"                      \
+                    ".popsection\n");                                          \
+}
 #else
 
 #define DTRACE_PROBE_TRACEPOINT(name, args...)
+#define DTRACE_PROTO_TRACEPOINT(name, proto...)
 
 #endif
 
@@ -221,6 +334,7 @@ typedef struct sdt_probedesc {
        type4, arg4, type5, arg5, type6, arg6, type7, arg7, type8, arg8) \
                                                        DTRACE_PROBE(name)
 #define DTRACE_PROBE_TRACEPOINT(name, args...)
+#define DTRACE_PROTO_TRACEPOINT(name, proto)
 
 #endif /* CONFIG_DTRACE */
 
index c913baf53e36d451c572f342d8c349ea20bcc136..4ab84ae8e3fdf5012009f4f0f269e88e3fb02f6b 100644 (file)
@@ -178,6 +178,7 @@ extern void syscall_unregfunc(void);
        static inline void trace_##name(proto)                          \
        {                                                               \
                DTRACE_PROBE_TRACEPOINT(name, args);                    \
+               DTRACE_PROTO_TRACEPOINT(name, proto);                   \
                if (static_key_false(&__tracepoint_##name.key))         \
                        __DO_TRACE(&__tracepoint_##name,                \
                                TP_PROTO(data_proto),                   \
@@ -241,6 +242,7 @@ extern void syscall_unregfunc(void);
        static inline void trace_##name(proto)                          \
        {                                                               \
                DTRACE_PROBE_TRACEPOINT(name, args);                    \
+               DTRACE_PROTO_TRACEPOINT(name, proto);                   \
        }                                                               \
        static inline void trace_##name##_rcuidle(proto)                \
        { }                                                             \