]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: eliminate need for arg counting in sdt macros
authorNick Alcock <nick.alcock@oracle.com>
Fri, 16 Sep 2016 09:17:18 +0000 (10:17 +0100)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 28 Oct 2016 12:45:45 +0000 (13:45 +0100)
The existing SDT probe macros are of the form

DTRACE_PROBEn(probe, ...)

where there must be as many args in ... as the 'n'.

This is implemented via terribly repetitive code in include/linux/sdt.h,
made much worse by the recent typed sdt additions.  Reduce
repetitiveness, and drop the 'n' variants of the macros.

All the complexity is hidden away in include/linux/sdt_internal.h.

It's derived from the tricks the perf probes were already using, but
improved to handle the zero-argument case and armoured against namespace
pollution with copious __ing.  Even when DTrace is turned off, we use a
do-nothing form of the same macro to verify that the number of arguments
in the probe is valid.

There is only one public macro now, DTRACE_PROBE(), and the usual thin
wrappers around it, which have also gone non-numbered (DTRACE_PROC,
DTRACE_IO, etc): all uses have been adjusted.

These macros use a family of semi-public macros, described below.

__DTRACE_DOUBLE_APPLY(type_macro, arg_macro, ...): This takes a type and
  arg macro and a set of pairs of arguments and calls the first argument
  on each pair with the type macro, the second with the arg macro, etc:
  if called with (type, arg, a, b, c, d) it will expand to something like

  type(a), arg(b), type(c), arg(d)

__DTRACE_DOUBLE_APPLY_NOCOMMA(type_macro, arg_macro, ...): As above, but
  omits all commas between arguments: the example above will yield

  type(a) arg(b) type(c) arg(d)

  (suitable for string concatenation).

__DTRACE_TYPE_APPLY(type_macro, arg_macro, ...): as above, but only
  calls the type_macro:

  type(a), type(c)

__DTRACE_ARG_APPLY(type_macro, arg_macro, ...): as above, but only
  calls the arg_macro:

  arg(b), arg(d)

__DTRACE_TYPE_APPLY_DEFAULT(type_macro, arg_macro, def, ...): as above,
  but takes an extra parameter to be used as a default when there are no
  args.  Calling it with (type, arg, void, a, b, c, d) will yield

  type(a), arg(b), type(c), arg(d)

  but calling it with (type, arg, void) will yield

  void

All the macros above take any number of pairs of arguments up to eight:
providing any other number, including odd numbers, is a compilation
error.

__DTRACE_APPLY(macro, ...): This is pre-existing, and calls the macro
  repeatedly with the specified args, comma-separated:

  m(a), m(b), m(c), ...

__DTRACE_APPLY_DEFAULT(macro, def, ...): Like DTRACE_TYPE_APPLY_DEFAULT,
  takes a default for use when there are no args.

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

fs/buffer.c
fs/exec.c
include/linux/sdt.h
include/linux/sdt_internal.h [new file with mode: 0644]
kernel/dtrace/dtrace_os.c
kernel/exit.c
kernel/fork.c
kernel/sched/core.c
kernel/signal.c
kernel/time/timer.c

index af04bc0a0498dd6b37b94a71c9005cbc3bdbb2cf..552bff810a1600481b83962d9a4aab37b8b25b40 100644 (file)
@@ -116,9 +116,9 @@ EXPORT_SYMBOL(buffer_check_dirty_writeback);
  */
 void __wait_on_buffer(struct buffer_head * bh)
 {
-       DTRACE_IO1(wait__start, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh);
+       DTRACE_IO(wait__start, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh);
        wait_on_bit_io(&bh->b_state, BH_Lock, TASK_UNINTERRUPTIBLE);
-       DTRACE_IO1(wait__done, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh);
+       DTRACE_IO(wait__done, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh);
 }
 EXPORT_SYMBOL(__wait_on_buffer);
 
@@ -2947,7 +2947,7 @@ static void end_bio_bh_io_sync(struct bio *bio, int err)
        if (unlikely (test_bit(BIO_QUIET,&bio->bi_flags)))
                set_bit(BH_Quiet, &bh->b_state);
 
-       DTRACE_IO2(done, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh, int, bio->bi_rw);
+       DTRACE_IO(done, struct buffer_head * : (bufinfo_t *, devinfo_t *, fileinfo_t *), bh, int, bio->bi_rw);
        bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags));
        bio_put(bio);
 }
@@ -3045,8 +3045,8 @@ int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags)
                rw |= REQ_PRIO;
 
        bio_get(bio);
-       DTRACE_IO2(start, struct buffer_head * : (bufinfo_t *, devinfo_t *,
-                                                 fileinfo_t *), bh, int, rw);
+       DTRACE_IO(start, struct buffer_head * : (bufinfo_t *, devinfo_t *,
+                                                fileinfo_t *), bh, int, rw);
        submit_bio(rw, bio);
 
        if (bio_flagged(bio, BIO_EOPNOTSUPP))
index b0c9033613a050082796b75cae9a0e98e3c05003..4315cf7b33c5e7ecdf58fb34228d3449708c8bea 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1524,7 +1524,7 @@ static int do_execveat_common(int fd, struct filename *filename,
        current->in_execve = 1;
 
        file = do_open_execat(fd, filename, flags);
-       DTRACE_PROC1(exec, char *, filename->name);
+       DTRACE_PROC(exec, char *, filename->name);
        retval = PTR_ERR(file);
        if (IS_ERR(file))
                goto out_unmark;
@@ -1626,7 +1626,7 @@ out_files:
                reset_files_struct(displaced);
 out_ret:
        putname(filename);
-       DTRACE_PROC1(exec__failure, int, retval);
+       DTRACE_PROC(exec__failure, int, retval);
        return retval;
 }
 
index ae194e4a466b8929146b2192d8594a2b154f830d..90a6ec003dcf2c02b3b546c8daaab87477c7a4b7 100644 (file)
-/* Copyright (C) 2011-2014 Oracle, Inc. */
+/* Copyright (C) 2011 -- 2016 Oracle, Inc. */
 
 #ifndef _LINUX_SDT_H_
 #define        _LINUX_SDT_H_
 
-#ifdef CONFIG_DTRACE
-
-#ifndef __KERNEL__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define        DTRACE_PROBE(provider, name) {                                  \
-       extern void __dtrace_##provider##___##name(void);               \
-       __dtrace_##provider##___##name();                               \
-}
-
-#define        DTRACE_PROBE1(provider, name, arg1) {                           \
-       extern void __dtrace_##provider##___##name(unsigned long);      \
-       __dtrace_##provider##___##name((unsigned long)arg1);            \
-}
-
-#define        DTRACE_PROBE2(provider, name, arg1, arg2) {                     \
-       extern void __dtrace_##provider##___##name(unsigned long,       \
-           unsigned long);                                             \
-       __dtrace_##provider##___##name((unsigned long)arg1,             \
-           (unsigned long)arg2);                                       \
-}
-
-#define        DTRACE_PROBE3(provider, name, arg1, arg2, arg3) {               \
-       extern void __dtrace_##provider##___##name(unsigned long,       \
-           unsigned long, unsigned long);                              \
-       __dtrace_##provider##___##name((unsigned long)arg1,             \
-           (unsigned long)arg2, (unsigned long)arg3);                  \
-}
-
-#define        DTRACE_PROBE4(provider, name, arg1, arg2, arg3, arg4) {         \
-       extern void __dtrace_##provider##___##name(unsigned long,       \
-           unsigned long, unsigned long, unsigned long);               \
-       __dtrace_##provider##___##name((unsigned long)arg1,             \
-           (unsigned long)arg2, (unsigned long)arg3,                   \
-           (unsigned long)arg4);                                       \
-}
-
-#define        DTRACE_PROBE5(provider, name, arg1, arg2, arg3, arg4, arg5) {   \
-       extern void __dtrace_##provider##___##name(unsigned long,       \
-           unsigned long, unsigned long, unsigned long, unsigned long);\
-       __dtrace_##provider##___##name((unsigned long)arg1,             \
-           (unsigned long)arg2, (unsigned long)arg3,                   \
-           (unsigned long)arg4, (unsigned long)arg5);                  \
-}
-
-#ifdef __cplusplus
-}
-#endif
+#include <linux/sdt_internal.h>
 
-#else /* __KERNEL__ */
+#ifdef CONFIG_DTRACE
 
 #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();                                        \
-}
-
-#define        DTRACE_PROBE1(name, type1, arg1)        {                       \
-       extern void __dtrace_probe_##name(uintptr_t);                   \
-       __dtrace_probe_##name((uintptr_t)(arg1));                       \
+#define        DTRACE_PROBE(name, ...) {                               \
+       extern void __dtrace_probe_##name(__DTRACE_TYPE_APPLY_DEFAULT(__DTRACE_UINTPTR_EACH, void, ## __VA_ARGS__)); \
+       __dtrace_probe_##name(__DTRACE_ARG_APPLY(__DTRACE_UINTCAST_EACH, ## __VA_ARGS__)); \
        asm volatile(".pushsection _dtrace_sdt_names, \"a\", @progbits\n" \
-                    PROBENAME_STR(name)                                \
+                    ".ascii \"" __stringify(name) "\"\n"               \
                     ".byte 0\n"                                        \
                     ".popsection\n"                                    \
                     ".pushsection _dtrace_sdt_args, \"a\", @progbits\n" \
-                    ARG_STR(type1)                                     \
+                    __DTRACE_TYPE_APPLY_NOCOMMA(__DTRACE_TYPE_EACH, ## __VA_ARGS__) \
                     ".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,                   \
-       type3, arg3, type4, arg4) {                                     \
-       extern void __dtrace_probe_##name(uintptr_t, uintptr_t,         \
-           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,                   \
-       type3, arg3, type4, arg4, type5, arg5) {                        \
-       extern void __dtrace_probe_##name(uintptr_t, uintptr_t,         \
-           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,                   \
-       type3, arg3, type4, arg4, type5, arg5, type6, arg6) {           \
-       extern void __dtrace_probe_##name(uintptr_t, uintptr_t,         \
-           uintptr_t, uintptr_t, uintptr_t, uintptr_t);                \
-       __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,      \
-       type4, arg4, type5, arg5, type6, arg6, type7, arg7) {           \
-       extern void __dtrace_probe_##name(uintptr_t, uintptr_t,         \
-           uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);     \
-       __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,      \
-       type4, arg4, type5, arg5, type6, arg6, type7, arg7, type8, arg8) { \
-       extern void __dtrace_probe_##name(uintptr_t, uintptr_t,         \
-           uintptr_t, uintptr_t, uintptr_t, uintptr_t,                 \
-           uintptr_t, uintptr_t);                                      \
-       __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");                                  \
+                    ".popsection\n");                                  \
 }
 
 #ifdef CONFIG_DT_SDT_PERF
 
-/*
- * 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 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.
- */
-#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)
-#define DTRACE_APPLY_3(m, x1, x2, x3) m(x1), m(x2), m(x3)
-#define DTRACE_APPLY_4(m, x1, x2, x3, x4) m(x1), m(x2), m(x3), m(x4)
-#define DTRACE_APPLY_5(m, x1, x2, x3, x4, x5) m(x1), m(x2), m(x3), m(x4), m(x5)
-#define DTRACE_APPLY_6(m, x1, x2, x3, x4, x5, x6) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6)
-#define DTRACE_APPLY_7(m, x1, x2, x3, x4, x5, x6, x7) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7)
-#define DTRACE_APPLY_8(m, x1, x2, x3, x4, x5, x6, x7, x8) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-
-/*
- * Without investigation I went ahead and assumed the most arguments that could
- * be passed would be 8, but this is purely arbitrary. However, inexplicably
- * there are existing tracepoints that pass as many as 18 arguments!
- */
-
-#define DTRACE_APPLY_9(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_10(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_11(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_12(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_13(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_14(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_15(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_16(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_17(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-#define DTRACE_APPLY_18(m, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
-
-/*
- * Convert everything to the appropriate integral type, unless too large to fit
- * into any of them, in which case its address is taken instead.
- */
-
-#define DTRACE_UINTPTR_CAST_EACH(x) ({                                 \
+#define __DTRACE_UINTPTR_CAST_EACH(x) ({                               \
   union {                                                              \
     typeof((x)) __val;                                                 \
     unsigned char __c;                                                 \
@@ -282,26 +38,26 @@ extern "C" {
   __builtin_choose_expr(sizeof(__u.__val) == sizeof(__u.__l), __u.__l,         \
   __builtin_choose_expr(sizeof(__u.__val) == sizeof(__u.__ll), __u.__ll,\
   (uintptr_t)&(__u.__val))))));})
-#define DTRACE_UINTPTR_EACH(x) uintptr_t
 
-#define DTRACE_PROBE_TRACEPOINT(name, args...) {                       \
-       extern void __dtrace_probe___perf_##name(DTRACE_APPLY(DTRACE_UINTPTR_EACH, args)); \
-       __dtrace_probe___perf_##name(DTRACE_APPLY(DTRACE_UINTPTR_CAST_EACH, args));     \
+#define DTRACE_PROBE_TRACEPOINT(name, ...) {                           \
+       extern void __dtrace_probe___perf_##name(__DTRACE_APPLY(__DTRACE_UINTPTR_EACH, ## __VA_ARGS__)); \
+       __dtrace_probe___perf_##name(__DTRACE_APPLY(__DTRACE_UINTPTR_CAST_EACH, ## __VA_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");                                          \
+#define DTRACE_PROTO_TRACEPOINT(name, ...) {                           \
+       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" \
+                    ".ascii \"" __stringify(__VA_ARGS__) "\"\n"        \
+                    ".byte 0\n"                                        \
+                    ".popsection\n");                                  \
 }
 #else
 
-#define DTRACE_PROBE_TRACEPOINT(name, args...)
-#define DTRACE_PROTO_TRACEPOINT(name, proto...)
+#define DTRACE_PROBE_TRACEPOINT(name, ...)
+#define DTRACE_PROTO_TRACEPOINT(name, ...)
 
 #endif
 
@@ -309,301 +65,66 @@ typedef struct sdt_probedesc {
        char                    *sdpd_name;     /* probe name */
        char                    *sdpd_func;     /* probe function */
 #ifndef __GENKSYMS__
-       char                    *sdpd_args;     /* arg string */
+       const char              *sdpd_args;     /* arg string */
 #endif
        unsigned long           sdpd_offset;    /* offset of call in text */
        struct sdt_probedesc    *sdpd_next;     /* next static probe */
 } sdt_probedesc_t;
 
-#endif /* __KERNEL__ */
-
 #else /* ! CONFIG_DTRACE */
 
-#define        DTRACE_PROBE(name)                              do { } while (0)
-#define        DTRACE_PROBE1(name, type1, arg1)                DTRACE_PROBE(name)
-#define        DTRACE_PROBE2(name, type1, arg1, type2, arg2)   DTRACE_PROBE(name)
-#define        DTRACE_PROBE3(name, type1, arg1, type2, arg2, type3, arg3)      \
-                                                       DTRACE_PROBE(name)
-#define        DTRACE_PROBE4(name, type1, arg1, type2, arg2, type3, arg3,      \
-                       type4, arg4)                    DTRACE_PROBE(name)
-#define        DTRACE_PROBE5(name, type1, arg1, type2, arg2, type3, arg3,      \
-                       type4, arg4, type5, arg5)       DTRACE_PROBE(name)
-#define        DTRACE_PROBE6(name, type1, arg1, type2, arg2, type3, arg3,      \
-       type4, arg4, type5, arg5, type6, arg6)          DTRACE_PROBE(name)
-#define        DTRACE_PROBE7(name, type1, arg1, type2, arg2, type3, arg3,      \
-       type4, arg4, type5, arg5, type6, arg6, type7, arg7)             \
-                                                       DTRACE_PROBE(name)
-#define        DTRACE_PROBE8(name, type1, arg1, type2, arg2, type3, arg3,      \
-       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)
+/*
+ * This apparently redundant call serves to validate the DTRACE_PROBE has the
+ * right number of args even when dtrace is turned off.
+ */
+#define        DTRACE_PROBE(name, ...)                                         \
+       __DTRACE_DOUBLE_APPLY_NOCOMMA(__DTRACE_NONE, __DTRACE_NONE, ## __VA_ARGS__)     \
+       do { } while (0)
+#define DTRACE_PROBE_TRACEPOINT(name, ...)
+#define DTRACE_PROTO_TRACEPOINT(name, ...)
 
 #endif /* CONFIG_DTRACE */
 
-#define        DTRACE_SCHED(name)                                              \
-       DTRACE_PROBE(__sched_##name);
-
-#define        DTRACE_SCHED1(name, type1, arg1)                                \
-       DTRACE_PROBE1(__sched_##name, type1, arg1);
-
-#define        DTRACE_SCHED2(name, type1, arg1, type2, arg2)                   \
-       DTRACE_PROBE2(__sched_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_SCHED3(name, type1, arg1, type2, arg2, type3, arg3)      \
-       DTRACE_PROBE3(__sched_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_SCHED4(name, type1, arg1, type2, arg2,                   \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__sched_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_PROC(name)                                               \
-       DTRACE_PROBE(__proc_##name);
-
-#define        DTRACE_PROC1(name, type1, arg1)                                 \
-       DTRACE_PROBE1(__proc_##name, type1, arg1);
-
-#define        DTRACE_PROC2(name, type1, arg1, type2, arg2)                    \
-       DTRACE_PROBE2(__proc_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_PROC3(name, type1, arg1, type2, arg2, type3, arg3)       \
-       DTRACE_PROBE3(__proc_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_PROC4(name, type1, arg1, type2, arg2,                    \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__proc_##name, type1, arg1, type2, arg2,          \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_IO(name)                                                 \
-       DTRACE_PROBE(__io_##name);
-
-#define        DTRACE_IO1(name, type1, arg1)                                   \
-       DTRACE_PROBE1(__io_##name, type1, arg1);
-
-#define        DTRACE_IO2(name, type1, arg1, type2, arg2)                      \
-       DTRACE_PROBE2(__io_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_IO3(name, type1, arg1, type2, arg2, type3, arg3) \
-       DTRACE_PROBE3(__io_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_IO4(name, type1, arg1, type2, arg2,                      \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__io_##name, type1, arg1, type2, arg2,            \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_ISCSI_2(name, type1, arg1, type2, arg2)                  \
-       DTRACE_PROBE2(__iscsi_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_ISCSI_3(name, type1, arg1, type2, arg2, type3, arg3)     \
-       DTRACE_PROBE3(__iscsi_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_ISCSI_4(name, type1, arg1, type2, arg2,                  \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__iscsi_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_ISCSI_5(name, type1, arg1, type2, arg2,                  \
-    type3, arg3, type4, arg4, type5, arg5)                             \
-       DTRACE_PROBE5(__iscsi_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4, type5, arg5);
-
-#define        DTRACE_ISCSI_6(name, type1, arg1, type2, arg2,                  \
-    type3, arg3, type4, arg4, type5, arg5, type6, arg6)                        \
-       DTRACE_PROBE6(__iscsi_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6);
-
-#define        DTRACE_ISCSI_7(name, type1, arg1, type2, arg2,                  \
-    type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7)   \
-       DTRACE_PROBE7(__iscsi_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6,         \
-           type7, arg7);
-
-#define        DTRACE_ISCSI_8(name, type1, arg1, type2, arg2,                  \
-    type3, arg3, type4, arg4, type5, arg5, type6, arg6,                        \
-    type7, arg7, type8, arg8)                                          \
-       DTRACE_PROBE8(__iscsi_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6,         \
-           type7, arg7, type8, arg8);
-
-#define        DTRACE_NFSV3_3(name, type1, arg1, type2, arg2,                  \
-    type3, arg3)                                                       \
-       DTRACE_PROBE3(__nfsv3_##name, type1, arg1, type2, arg2,         \
-           type3, arg3);
-#define        DTRACE_NFSV3_4(name, type1, arg1, type2, arg2,                  \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__nfsv3_##name, type1, arg1, type2, arg2,         \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_NFSV4_1(name, type1, arg1) \
-       DTRACE_PROBE1(__nfsv4_##name, type1, arg1);
-
-#define        DTRACE_NFSV4_2(name, type1, arg1, type2, arg2) \
-       DTRACE_PROBE2(__nfsv4_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_NFSV4_3(name, type1, arg1, type2, arg2, type3, arg3) \
-       DTRACE_PROBE3(__nfsv4_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_SMB_1(name, type1, arg1) \
-       DTRACE_PROBE1(__smb_##name, type1, arg1);
-
-#define        DTRACE_SMB_2(name, type1, arg1, type2, arg2) \
-       DTRACE_PROBE2(__smb_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_IP(name)                                         \
-       DTRACE_PROBE(__ip_##name);
-
-#define        DTRACE_IP1(name, type1, arg1)                                   \
-       DTRACE_PROBE1(__ip_##name, type1, arg1);
-
-#define        DTRACE_IP2(name, type1, arg1, type2, arg2)                      \
-       DTRACE_PROBE2(__ip_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_IP3(name, type1, arg1, type2, arg2, type3, arg3) \
-       DTRACE_PROBE3(__ip_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_IP4(name, type1, arg1, type2, arg2,                      \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__ip_##name, type1, arg1, type2, arg2,            \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_IP5(name, type1, arg1, type2, arg2,                      \
-    type3, arg3, type4, arg4, type5, arg5)                             \
-       DTRACE_PROBE5(__ip_##name, type1, arg1, type2, arg2,            \
-           type3, arg3, type4, arg4, type5, arg5);
-
-#define        DTRACE_IP6(name, type1, arg1, type2, arg2,                      \
-    type3, arg3, type4, arg4, type5, arg5, type6, arg6)                        \
-       DTRACE_PROBE6(__ip_##name, type1, arg1, type2, arg2,            \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6);
-
-#define        DTRACE_IP7(name, type1, arg1, type2, arg2, type3, arg3,         \
-    type4, arg4, type5, arg5, type6, arg6, type7, arg7)                        \
-       DTRACE_PROBE7(__ip_##name, type1, arg1, type2, arg2,            \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6,         \
-           type7, arg7);
-
-#define        DTRACE_TCP(name)                                                \
-       DTRACE_PROBE(__tcp_##name);
-
-#define        DTRACE_TCP1(name, type1, arg1)                                  \
-       DTRACE_PROBE1(__tcp_##name, type1, arg1);
-
-#define        DTRACE_TCP2(name, type1, arg1, type2, arg2)                     \
-       DTRACE_PROBE2(__tcp_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_TCP3(name, type1, arg1, type2, arg2, type3, arg3)        \
-       DTRACE_PROBE3(__tcp_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_TCP4(name, type1, arg1, type2, arg2,                     \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__tcp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_TCP5(name, type1, arg1, type2, arg2,                     \
-    type3, arg3, type4, arg4, type5, arg5)                             \
-       DTRACE_PROBE5(__tcp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5);
-
-#define        DTRACE_TCP6(name, type1, arg1, type2, arg2,                     \
-    type3, arg3, type4, arg4, type5, arg5, type6, arg6)                        \
-       DTRACE_PROBE6(__tcp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6);
-
-#define        DTRACE_UDP(name)                                                \
-       DTRACE_PROBE(__udp_##name);
-
-#define        DTRACE_UDP1(name, type1, arg1)                                  \
-       DTRACE_PROBE1(__udp_##name, type1, arg1);
-
-#define        DTRACE_UDP2(name, type1, arg1, type2, arg2)                     \
-       DTRACE_PROBE2(__udp_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_UDP3(name, type1, arg1, type2, arg2, type3, arg3)        \
-       DTRACE_PROBE3(__udp_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_UDP4(name, type1, arg1, type2, arg2,                     \
-    type3, arg3, type4, arg4)                                          \
-       DTRACE_PROBE4(__udp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4);
-
-#define        DTRACE_UDP5(name, type1, arg1, type2, arg2,                     \
-    type3, arg3, type4, arg4, type5, arg5)                             \
-       DTRACE_PROBE5(__udp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5);
-
-
-#define        DTRACE_SYSEVENT2(name, type1, arg1, type2, arg2)                \
-       DTRACE_PROBE2(__sysevent_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_XPV(name)                                                \
-       DTRACE_PROBE(__xpv_##name);
-
-#define        DTRACE_XPV1(name, type1, arg1)                                  \
-       DTRACE_PROBE1(__xpv_##name, type1, arg1);
-
-#define        DTRACE_XPV2(name, type1, arg1, type2, arg2)                     \
-       DTRACE_PROBE2(__xpv_##name, type1, arg1, type2, arg2);
-
-#define        DTRACE_XPV3(name, type1, arg1, type2, arg2, type3, arg3)        \
-       DTRACE_PROBE3(__xpv_##name, type1, arg1, type2, arg2, type3, arg3);
-
-#define        DTRACE_XPV4(name, type1, arg1, type2, arg2, type3, arg3,        \
-           type4, arg4)                                                \
-       DTRACE_PROBE4(__xpv_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4);
+#define        DTRACE_SCHED(name, ...)                                         \
+       DTRACE_PROBE(__sched_##name, ## __VA_ARGS__);
 
-#define        DTRACE_FC_1(name, type1, arg1) \
-       DTRACE_PROBE1(__fc_##name, type1, arg1);
+#define        DTRACE_PROC(name, ...)                                          \
+       DTRACE_PROBE(__proc_##name, ## __VA_ARGS__);
 
-#define        DTRACE_FC_2(name, type1, arg1, type2, arg2) \
-       DTRACE_PROBE2(__fc_##name, type1, arg1, type2, arg2);
+#define        DTRACE_IO(name, ...)                                            \
+       DTRACE_PROBE(__io_##name, ## __VA_ARGS__);
 
-#define        DTRACE_FC_3(name, type1, arg1, type2, arg2, type3, arg3) \
-       DTRACE_PROBE3(__fc_##name, type1, arg1, type2, arg2, type3, arg3);
+#define        DTRACE_ISCSI(name, ...)                                         \
+       DTRACE_PROBE(__iscsi_##name, ## __VA_ARGS__);
 
-#define        DTRACE_FC_4(name, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
-       DTRACE_PROBE4(__fc_##name, type1, arg1, type2, arg2, type3, arg3, \
-           type4, arg4);
+#define        DTRACE_NFSV3(name, ...)                                         \
+       DTRACE_PROBE(__nfsv3_##name, ## __VA_ARGS__);
 
-#define        DTRACE_FC_5(name, type1, arg1, type2, arg2, type3, arg3,        \
-           type4, arg4, type5, arg5)                                   \
-       DTRACE_PROBE5(__fc_##name, type1, arg1, type2, arg2, type3, arg3, \
-           type4, arg4, type5, arg5);
+#define        DTRACE_NFSV4(name, ...)                                         \
+       DTRACE_PROBE(__nfsv4_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_1(name, type1, arg1)                                 \
-       DTRACE_PROBE1(__srp_##name, type1, arg1);
+#define        DTRACE_SMB(name, ...)                                           \
+       DTRACE_PROBE(__smb_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_2(name, type1, arg1, type2, arg2)                    \
-       DTRACE_PROBE2(__srp_##name, type1, arg1, type2, arg2);
+#define        DTRACE_IP(name, ...)                                            \
+       DTRACE_PROBE(__ip_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_3(name, type1, arg1, type2, arg2, type3, arg3)       \
-       DTRACE_PROBE3(__srp_##name, type1, arg1, type2, arg2, type3, arg3);
+#define        DTRACE_TCP(name, ...)                                           \
+       DTRACE_PROBE(__tcp_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_4(name, type1, arg1, type2, arg2, type3, arg3,       \
-           type4, arg4)                                                \
-       DTRACE_PROBE4(__srp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4);
+#define        DTRACE_UDP(name, ...)                                           \
+       DTRACE_PROBE(__udp_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_5(name, type1, arg1, type2, arg2, type3, arg3,       \
-           type4, arg4, type5, arg5)                                   \
-       DTRACE_PROBE5(__srp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5);
+#define        DTRACE_SYSEVENT(name, ...)                                      \
+       DTRACE_PROBE(__sysevent_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_6(name, type1, arg1, type2, arg2, type3, arg3,       \
-           type4, arg4, type5, arg5, type6, arg6)                      \
-       DTRACE_PROBE6(__srp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6);
+#define        DTRACE_XPV(name, ...)                                           \
+       DTRACE_PROBE(__xpv_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_7(name, type1, arg1, type2, arg2, type3, arg3,       \
-           type4, arg4, type5, arg5, type6, arg6, type7, arg7)         \
-       DTRACE_PROBE7(__srp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7);
+#define        DTRACE_FC(name, ...)                                            \
+       DTRACE_PROBE(__fc_##name, ## __VA_ARGS__);
 
-#define        DTRACE_SRP_8(name, type1, arg1, type2, arg2, type3, arg3,       \
-           type4, arg4, type5, arg5, type6, arg6, type7, arg7, type8, arg8) \
-       DTRACE_PROBE8(__srp_##name, type1, arg1, type2, arg2,           \
-           type3, arg3, type4, arg4, type5, arg5, type6, arg6,         \
-           type7, arg7, type8, arg8);
+#define        DTRACE_SRP(name, ...)                                           \
+       DTRACE_PROBE(__srp_##name, ## __VA_ARGS__);
 
 #endif /* _LINUX_SDT_H_ */
diff --git a/include/linux/sdt_internal.h b/include/linux/sdt_internal.h
new file mode 100644 (file)
index 0000000..ca0edbe
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Hide away all the terrible macro magic.
+ *
+ * Copyright (C) 2016 Oracle, Inc.
+ */
+
+#ifndef _LINUX_SDT_INTERNAL_H_
+#define _LINUX_SDT_INTERNAL_H_
+
+/*
+ * This counts the number of args.
+ */
+#define __DTRACE_NARGS_SEQ(dummy,_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(dummy, ##__VA_ARGS__, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+/*
+ * 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)
+
+#define __DTRACE_COMMA ,
+#define __DTRACE_NO_COMMA
+#define __DTRACE_NONE(x)
+
+/*
+ * This will call two macros on each argument-pair passed in (the first two args
+ * are the names of the macros to call).  Its TYPE and NAME variants will throw
+ * away the name and type arguments, respectively. __DTRACE_*_APPLY_NOCOMMA
+ * are like DTRACE_*_APPLY, but also omit the comma between arguments in the
+ * expansion of the macro.  DTRACE_TYPE_APPLY_DEFAULT lets you specify a default
+ * if no variadic args are provided.
+ */
+#define __DTRACE_DOUBLE_APPLY(type_macro, arg_macro, ...)              \
+       __DTRACE_CAT(__DTRACE_DOUBLE_APPLY_,                            \
+                    __DTRACE_NARGS(__VA_ARGS__))(type_macro,           \
+                                                 arg_macro, __DTRACE_COMMA, \
+                                                 __DTRACE_COMMA, , ## __VA_ARGS__)
+#define __DTRACE_DOUBLE_APPLY_NOCOMMA(type_macro, arg_macro, ...)              \
+       __DTRACE_CAT(__DTRACE_DOUBLE_APPLY_,                            \
+                    __DTRACE_NARGS(__VA_ARGS__))(type_macro,           \
+                                                 arg_macro, __DTRACE_NO_COMMA, \
+                                                 __DTRACE_NO_COMMA, , ## __VA_ARGS__)
+#define __DTRACE_TYPE_APPLY(type_macro, ...)                           \
+       __DTRACE_CAT(__DTRACE_DOUBLE_APPLY_,                            \
+                    __DTRACE_NARGS(__VA_ARGS__))(type_macro,           \
+                                                 __DTRACE_NONE, __DTRACE_NO_COMMA, \
+                                                 __DTRACE_COMMA, , ## __VA_ARGS__)
+#define __DTRACE_TYPE_APPLY_NOCOMMA(type_macro, ...)                   \
+       __DTRACE_CAT(__DTRACE_DOUBLE_APPLY_,                            \
+                    __DTRACE_NARGS(__VA_ARGS__))(type_macro,           \
+                                                 __DTRACE_NONE, __DTRACE_NO_COMMA, \
+                                                 __DTRACE_NO_COMMA, , ## __VA_ARGS__)
+#define __DTRACE_TYPE_APPLY_DEFAULT(type_macro, def, ...)              \
+       __DTRACE_CAT(__DTRACE_DOUBLE_APPLY_,                            \
+                    __DTRACE_NARGS(__VA_ARGS__))(type_macro,           \
+                                                 __DTRACE_NONE, __DTRACE_NO_COMMA, \
+                                                 __DTRACE_COMMA, def, ## __VA_ARGS__)
+#define __DTRACE_ARG_APPLY(arg_macro, ...)                             \
+       __DTRACE_CAT(__DTRACE_DOUBLE_APPLY_,                            \
+                    __DTRACE_NARGS(__VA_ARGS__))(__DTRACE_NONE,        \
+                                                 arg_macro, __DTRACE_NO_COMMA, \
+                                                 __DTRACE_COMMA, , ## __VA_ARGS__)
+#define __DTRACE_DOUBLE_APPLY_0(t, a, comma_t, comma_a, def) def
+#define __DTRACE_DOUBLE_APPLY_2(t, a, comma_t, comma_a, def, type1, arg1) \
+       t(type1) comma_t a(arg1)
+#define __DTRACE_DOUBLE_APPLY_4(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2)
+#define __DTRACE_DOUBLE_APPLY_6(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2, type3, arg3) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2) comma_a \
+       t(type3) comma_t a(arg3)
+#define __DTRACE_DOUBLE_APPLY_8(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2, type3, arg3, type4, arg4) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2) comma_a \
+       t(type3) comma_t a(arg3) comma_a t(type4) comma_t a(arg4)
+#define __DTRACE_DOUBLE_APPLY_10(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2) comma_a \
+       t(type3) comma_t a(arg3) comma_a t(type4) comma_t a(arg4) comma_a \
+       t(type5) comma_t a(arg5)
+#define __DTRACE_DOUBLE_APPLY_12(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2) comma_a \
+       t(type3) comma_t a(arg3) comma_a t(type4) comma_t a(arg4) comma_a \
+       t(type5) comma_t a(arg5) comma_a t(type6) comma_t a(arg6)
+#define __DTRACE_DOUBLE_APPLY_14(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2) comma_a \
+       t(type3) comma_t a(arg3) comma_a t(type4) comma_t a(arg4) comma_a \
+       t(type5) comma_t a(arg5) comma_a t(type6) comma_t a(arg6) comma_a \
+       t(type7) comma_t a(arg7)
+#define __DTRACE_DOUBLE_APPLY_16(t, a, comma_t, comma_a, def, type1, arg1, type2, arg2, type3, arg3, type4, arg4, type5, arg5, type6, arg6, type7, arg7, type8, arg8) \
+       t(type1) comma_t a(arg1) comma_a t(type2) comma_t a(arg2) comma_a \
+       t(type3) comma_t a(arg3) comma_a t(type4) comma_t a(arg4) comma_a \
+       t(type5) comma_t a(arg5) comma_a t(type6) comma_t a(arg6) comma_a \
+       t(type7) comma_t a(arg7) comma_a t(type8) comma_t a(arg8)
+
+#define __DTRACE_DOUBLE_APPLY_ERROR Error: type specified without arg.
+#define __DTRACE_DOUBLE_APPLY_1 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_3 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_5 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_7 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_9 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_11 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_13 __DTRACE_DOUBLE_APPLY_ERROR
+#define __DTRACE_DOUBLE_APPLY_15 __DTRACE_DOUBLE_APPLY_ERROR
+
+#define __DTRACE_UINTPTR_EACH(x) uintptr_t
+
+#define __DTRACE_UINTCAST_EACH(x) (uintptr_t)(x)
+#define __DTRACE_TYPE_EACH(x) ".ascii \"" __stringify(x) ",\"\n"
+
+/*
+ * Convert everything to the appropriate integral type, unless too large to fit
+ * into any of them, in which case its address is taken instead.
+ */
+
+/*
+ * This will call a macro on each argument passed in, with optional default for
+ * zero args.
+ */
+#define __DTRACE_APPLY(macro, ...) __DTRACE_CAT(__DTRACE_APPLY_, __DTRACE_NARGS(__VA_ARGS__))(macro, , ## __VA_ARGS__)
+#define __DTRACE_APPLY_DEFAULT(macro, def, ...) __DTRACE_CAT(__DTRACE_APPLY_, __DTRACE_NARGS(__VA_ARGS__))(macro, def, ## __VA_ARGS__)
+#define __DTRACE_APPLY_0(m, def) def
+#define __DTRACE_APPLY_1(m, def, x1) m(x1)
+#define __DTRACE_APPLY_2(m, def, x1, x2) m(x1), m(x2)
+#define __DTRACE_APPLY_3(m, def, x1, x2, x3) m(x1), m(x2), m(x3)
+#define __DTRACE_APPLY_4(m, def, x1, x2, x3, x4) m(x1), m(x2), m(x3), m(x4)
+#define __DTRACE_APPLY_5(m, def, x1, x2, x3, x4, x5) m(x1), m(x2), m(x3), m(x4), m(x5)
+#define __DTRACE_APPLY_6(m, def, x1, x2, x3, x4, x5, x6) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6)
+#define __DTRACE_APPLY_7(m, def, x1, x2, x3, x4, x5, x6, x7) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7)
+#define __DTRACE_APPLY_8(m, def, x1, x2, x3, x4, x5, x6, x7, x8) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+
+/*
+ * DTrace probe args currently top out at 8, but this is purely
+ * arbitrary. However, there are existing perf tracepoints that pass as many as
+ * 18 arguments, so we must extend APPLY that far.
+ */
+
+#define __DTRACE_APPLY_9(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_10(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_11(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_12(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_13(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_14(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_15(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_16(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_17(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+#define __DTRACE_APPLY_18(m, def, x1, x2, x3, x4, x5, x6, x7, x8, ...) m(x1), m(x2), m(x3), m(x4), m(x5), m(x6), m(x7), m(x8)
+
+#endif /* _LINUX_SDT_INTERNAL_H */
index 48947b6deebcdd7d42f22f7808a7fff687f8eaf2..80144415ba06931a7793001394aebf03d635dff8 100644 (file)
@@ -275,9 +275,9 @@ static void psinfo_cleaner(struct work_struct *work)
        spin_unlock_irqrestore(&psinfo_lock, flags);
 
 #ifdef CONFIG_DT_DEBUG
-       DTRACE_PROBE8(test, uint64_t, 10, uint64_t, 20, uint64_t, 30,
-                           uint64_t, 40, uint64_t, 50, uint64_t, 60,
-                           uint64_t, 70, uint64_t, 80);
+       DTRACE_PROBE(test, uint64_t, 10, uint64_t, 20, uint64_t, 30,
+                          uint64_t, 40, uint64_t, 50, uint64_t, 60,
+                          uint64_t, 70, uint64_t, 80);
 #endif
 
        while (psinfo) {
index 9a10eb70227ebb7c6edc4f4cc9eefa4508e6980c..17b27c1e057731abf164bc8b7466c33045bae589 100644 (file)
@@ -733,7 +733,7 @@ void do_exit(long code)
        taskstats_exit(tsk, group_dead);
 
        DTRACE_PROC(lwp__exit);
-       DTRACE_PROC1(exit, int, code & 0x80 ? 3 : code & 0x7f ? 2 : 1);
+       DTRACE_PROC(exit, int, code & 0x80 ? 3 : code & 0x7f ? 2 : 1);
 
 #ifdef CONFIG_DTRACE
        dtrace_task_cleanup(tsk);
index d23b00fc4cf49a437cc5578c8b270c2e6aef3298..fba3b907b8adce1204a9df2a0eca08720e8de976 100644 (file)
@@ -1761,8 +1761,8 @@ long do_fork(unsigned long clone_flags,
                }
 
                put_pid(pid);
-               DTRACE_PROC1(lwp__create, struct task_struct * : (lwpsinfo_t *, psinfo_t *), p);
-               DTRACE_PROC1(create, struct task_struct * : psinfo_t *, p);
+               DTRACE_PROC(lwp__create, struct task_struct * : (lwpsinfo_t *, psinfo_t *), p);
+               DTRACE_PROC(create, struct task_struct * : psinfo_t *, p);
        } else {
                nr = PTR_ERR(p);
        }
index aa285729aa5d7317bfdf4732c6823946e55a7bf6..1224736152027cc292d70efb35e0b307b86188cf 100644 (file)
@@ -805,9 +805,9 @@ static void set_load_weight(struct task_struct *p)
 
 static void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
 {
-       DTRACE_SCHED2(enqueue, struct task_struct * : (lwpsinfo_t *,
-                                                      psinfo_t *), p,
-                              cpuinfo_t *, rq->dtrace_cpu_info);
+       DTRACE_SCHED(enqueue, struct task_struct * : (lwpsinfo_t *,
+                                                     psinfo_t *), p,
+                             cpuinfo_t *, rq->dtrace_cpu_info);
        update_rq_clock(rq);
        sched_info_queued(rq, p);
        p->sched_class->enqueue_task(rq, p, flags);
@@ -815,10 +815,10 @@ static void enqueue_task(struct rq *rq, struct task_struct *p, int flags)
 
 static void dequeue_task(struct rq *rq, struct task_struct *p, int flags)
 {
-       DTRACE_SCHED3(dequeue, struct task_struct * : (lwpsinfo_t *,
-                                                      psinfo_t *), p,
-                              cpuinfo_t *, rq->dtrace_cpu_info,
-                              int, 0);
+       DTRACE_SCHED(dequeue, struct task_struct * : (lwpsinfo_t *,
+                                                     psinfo_t *), p,
+                             cpuinfo_t *, rq->dtrace_cpu_info,
+                             int, 0);
        update_rq_clock(rq);
        sched_info_dequeued(rq, p);
        p->sched_class->dequeue_task(rq, p, flags);
@@ -1680,8 +1680,8 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
        success = 1; /* we're going to change ->state */
        cpu = task_cpu(p);
 
-       DTRACE_SCHED1(wakeup, struct task_struct * : (lwpsinfo_t *,
-                                                     psinfo_t *), p);
+       DTRACE_SCHED(wakeup, struct task_struct * : (lwpsinfo_t *,
+                                                    psinfo_t *), p);
 
        if (p->on_rq && ttwu_remote(p, wake_flags))
                goto stat;
@@ -2190,8 +2190,8 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev,
        trace_sched_switch(prev, next);
        sched_info_switch(rq, prev, next);
        perf_event_task_sched_out(prev, next);
-       DTRACE_SCHED1(off__cpu, struct task_struct * : (lwpsinfo_t *,
-                                                       psinfo_t *), next);
+       DTRACE_SCHED(off__cpu, struct task_struct * : (lwpsinfo_t *,
+                                                      psinfo_t *), next);
        fire_sched_out_preempt_notifiers(prev, next);
        prepare_lock_switch(rq, next);
        prepare_arch_switch(next);
@@ -3134,8 +3134,8 @@ void set_user_nice(struct task_struct *p, long nice)
        p->prio = effective_prio(p);
        delta = p->prio - old_prio;
 
-       DTRACE_SCHED2(change__pri, struct task_struct * : (lwpsinfo_t *,
-                                                          psinfo_t *), p,
+       DTRACE_SCHED(change__pri, struct task_struct * : (lwpsinfo_t *,
+                                                         psinfo_t *), p,
                      int, old_prio);
        if (queued) {
                enqueue_task(rq, p, 0);
@@ -4250,9 +4250,9 @@ SYSCALL_DEFINE0(sched_yield)
        do_raw_spin_unlock(&rq->lock);
        sched_preempt_enable_no_resched();
 
-       DTRACE_SCHED1(surrender,
-                     struct task_struct * : (lwpsinfo_t *, psinfo_t *),
-                     current);
+       DTRACE_SCHED(surrender,
+                    struct task_struct * : (lwpsinfo_t *, psinfo_t *),
+                    current);
        schedule();
 
        return 0;
@@ -4407,9 +4407,9 @@ out_irq:
        local_irq_restore(flags);
 
        if (yielded > 0) {
-               DTRACE_SCHED1(surrender,
-                             struct task_struct * : (lwpsinfo_t *, psinfo_t *),
-                             curr);
+               DTRACE_SCHED(surrender,
+                            struct task_struct * : (lwpsinfo_t *, psinfo_t *),
+                            curr);
                schedule();
        }
 
index ac6c3e8b823e3032ba49ecdc9a1ecaf81317e78b..0a33012f4571668bc7958960112933fc47a1b623 100644 (file)
@@ -1034,9 +1034,9 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
        result = TRACE_SIGNAL_IGNORED;
        if (!prepare_signal(sig, t,
                            from_ancestor_ns || (info == SEND_SIG_FORCED))) {
-               DTRACE_PROC2(signal__discard,
-                            struct task_struct * : (lwpsinfo_t *, psinfo_t *), t,
-                            int, sig);
+               DTRACE_PROC(signal__discard,
+                           struct task_struct * : (lwpsinfo_t *, psinfo_t *), t,
+                           int, sig);
                goto ret;
        }
 
@@ -1124,9 +1124,9 @@ out_set:
        signalfd_notify(t, sig);
        sigaddset(&pending->signal, sig);
        complete_signal(sig, t, group);
-       DTRACE_PROC2(signal__send,
-                    struct task_struct * : (lwpsinfo_t *, psinfo_t *), t,
-                    int, sig);
+       DTRACE_PROC(signal__send,
+                   struct task_struct * : (lwpsinfo_t *, psinfo_t *), t,
+                   int, sig);
 ret:
        trace_signal_generate(sig, info, t, group, result);
        return ret;
@@ -1613,9 +1613,9 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
        list_add_tail(&q->list, &pending->list);
        sigaddset(&pending->signal, sig);
        complete_signal(sig, t, group);
-       DTRACE_PROC2(signal__send,
-                    struct task_struct * : (lwpsinfo_t *, psinfo_t *), t,
-                    int, sig);
+       DTRACE_PROC(signal__send,
+                   struct task_struct * : (lwpsinfo_t *, psinfo_t *), t,
+                   int, sig);
        result = TRACE_SIGNAL_DELIVERED;
 out:
        trace_signal_generate(sig, &q->info, t, group, result);
@@ -2272,14 +2272,14 @@ relock:
 
                ka = &sighand->action[signr-1];
 
-               DTRACE_PROC3(signal__handle,
-                            int, signal->group_exit_code
+               DTRACE_PROC(signal__handle,
+                           int, signal->group_exit_code
                                                ? signal->group_exit_code
                                                : signr,
-                            siginfo_t *, ksig->ka.sa.sa_handler != SIG_DFL
+                           siginfo_t *, ksig->ka.sa.sa_handler != SIG_DFL
                                                ? NULL
                                                : &ksig->info,
-                            void (*)(void), ksig->ka.sa.sa_handler);
+                           void (*)(void), ksig->ka.sa.sa_handler);
 
                /* Trace actually delivered signals. */
                trace_signal_deliver(signr, &ksig->info, ka);
@@ -2867,7 +2867,7 @@ int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
        spin_unlock_irq(&tsk->sighand->siglock);
 
        if (sig) {
-               DTRACE_PROC1(signal__clear, int, sig);
+               DTRACE_PROC(signal__clear, int, sig);
                return sig;
        }
        return timeout ? -EINTR : -EAGAIN;
index b16eaa7fb044eb77a8e85987d0f855acd99f1f01..4476c4c22d5ecd91445513723e7f64823b03a4a4 100644 (file)
@@ -1391,8 +1391,8 @@ void update_process_times(int user_tick)
 {
        struct task_struct *p = current;
 
-       DTRACE_SCHED1(tick, struct task_struct * : (lwpsinfo_t *, psinfo_t *),
-                     p);
+       DTRACE_SCHED(tick, struct task_struct * : (lwpsinfo_t *, psinfo_t *),
+                    p);
 
        /* Note: this timer irq context must be accounted for as well. */
        account_process_tick(p, user_tick);