Commit b8e46d22dc7cb66c70aeec57fff6101dbd96f30d

Authored by Linus Torvalds

Merge tag 'trace-fixes-v3.16-rc1-v2' of git://git.kernel.org/pub/scm/linux/kerne…

…l/git/rostedt/linux-trace

Pull tracing cleanups and fixes from Steven Rostedt:
 "This includes three patches from Oleg Nesterov.  The first is a fix to
  a race condition that happens between enabling/disabling syscall
  tracepoints and new process creations (the check to go into the ptrace
  path for a process can be set when it shouldn't, or not set when it
  should).  Not a major bug but one that should be fixed and even
  applied to stable.

  The other two patches are cleanup/fixes that are not that critical,
  but for an -rc1 release would be nice to have.  They both deal with
  syscall tracepoints.

  It also includes a patch to introduce a new macro for the
  TRACE_EVENT() format called __field_struct().  Originally, __field()
  was used to record any variable into a trace event, but with the
  addition of setting the "is signed" attribute, the check causes
  anything but a primitive variable to fail to compile.  That is,
  structs and unions can't be used as they once were.  When the "is
  signed" check was introduce there were only primitive variables being
  recorded.  But that will change soon and it was reported that
  __field() causes build failures.

  To solve the __field() issue, __field_struct() is introduced to allow
  trace_events to be able to record complex types too"

* tag 'trace-fixes-v3.16-rc1-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  tracing: Add __field_struct macro for TRACE_EVENT()
  tracing: syscall_regfunc() should not skip kernel threads
  tracing: Change syscall_*regfunc() to check PF_KTHREAD and use for_each_process_thread()
  tracing: Fix syscall_*regfunc() vs copy_process() race

Showing 5 changed files Side-by-side Diff

include/trace/ftrace.h
... ... @@ -44,6 +44,12 @@
44 44 #undef __field_ext
45 45 #define __field_ext(type, item, filter_type) type item;
46 46  
  47 +#undef __field_struct
  48 +#define __field_struct(type, item) type item;
  49 +
  50 +#undef __field_struct_ext
  51 +#define __field_struct_ext(type, item, filter_type) type item;
  52 +
47 53 #undef __array
48 54 #define __array(type, item, len) type item[len];
49 55  
... ... @@ -122,6 +128,12 @@
122 128 #undef __field_ext
123 129 #define __field_ext(type, item, filter_type)
124 130  
  131 +#undef __field_struct
  132 +#define __field_struct(type, item)
  133 +
  134 +#undef __field_struct_ext
  135 +#define __field_struct_ext(type, item, filter_type)
  136 +
125 137 #undef __array
126 138 #define __array(type, item, len)
127 139  
128 140  
... ... @@ -315,9 +327,21 @@
315 327 if (ret) \
316 328 return ret;
317 329  
  330 +#undef __field_struct_ext
  331 +#define __field_struct_ext(type, item, filter_type) \
  332 + ret = trace_define_field(event_call, #type, #item, \
  333 + offsetof(typeof(field), item), \
  334 + sizeof(field.item), \
  335 + 0, filter_type); \
  336 + if (ret) \
  337 + return ret;
  338 +
318 339 #undef __field
319 340 #define __field(type, item) __field_ext(type, item, FILTER_OTHER)
320 341  
  342 +#undef __field_struct
  343 +#define __field_struct(type, item) __field_struct_ext(type, item, FILTER_OTHER)
  344 +
321 345 #undef __array
322 346 #define __array(type, item, len) \
323 347 do { \
... ... @@ -379,6 +403,12 @@
379 403 #undef __field_ext
380 404 #define __field_ext(type, item, filter_type)
381 405  
  406 +#undef __field_struct
  407 +#define __field_struct(type, item)
  408 +
  409 +#undef __field_struct_ext
  410 +#define __field_struct_ext(type, item, filter_type)
  411 +
382 412 #undef __array
383 413 #define __array(type, item, len)
384 414  
... ... @@ -549,6 +579,9 @@
549 579  
550 580 #undef __field
551 581 #define __field(type, item)
  582 +
  583 +#undef __field_struct
  584 +#define __field_struct(type, item)
552 585  
553 586 #undef __array
554 587 #define __array(type, item, len)
include/trace/syscall.h
... ... @@ -4,6 +4,7 @@
4 4 #include <linux/tracepoint.h>
5 5 #include <linux/unistd.h>
6 6 #include <linux/ftrace_event.h>
  7 +#include <linux/thread_info.h>
7 8  
8 9 #include <asm/ptrace.h>
9 10  
... ... @@ -31,6 +32,20 @@
31 32 struct ftrace_event_call *enter_event;
32 33 struct ftrace_event_call *exit_event;
33 34 };
  35 +
  36 +#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
  37 +static inline void syscall_tracepoint_update(struct task_struct *p)
  38 +{
  39 + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
  40 + set_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
  41 + else
  42 + clear_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
  43 +}
  44 +#else
  45 +static inline void syscall_tracepoint_update(struct task_struct *p)
  46 +{
  47 +}
  48 +#endif
34 49  
35 50 #endif /* _TRACE_SYSCALL_H */
... ... @@ -1487,7 +1487,9 @@
1487 1487  
1488 1488 total_forks++;
1489 1489 spin_unlock(&current->sighand->siglock);
  1490 + syscall_tracepoint_update(p);
1490 1491 write_unlock_irq(&tasklist_lock);
  1492 +
1491 1493 proc_fork_connector(p);
1492 1494 cgroup_post_fork(p);
1493 1495 if (clone_flags & CLONE_THREAD)
... ... @@ -492,33 +492,29 @@
492 492  
493 493 void syscall_regfunc(void)
494 494 {
495   - unsigned long flags;
496   - struct task_struct *g, *t;
  495 + struct task_struct *p, *t;
497 496  
498 497 if (!sys_tracepoint_refcount) {
499   - read_lock_irqsave(&tasklist_lock, flags);
500   - do_each_thread(g, t) {
501   - /* Skip kernel threads. */
502   - if (t->mm)
503   - set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
504   - } while_each_thread(g, t);
505   - read_unlock_irqrestore(&tasklist_lock, flags);
  498 + read_lock(&tasklist_lock);
  499 + for_each_process_thread(p, t) {
  500 + set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
  501 + }
  502 + read_unlock(&tasklist_lock);
506 503 }
507 504 sys_tracepoint_refcount++;
508 505 }
509 506  
510 507 void syscall_unregfunc(void)
511 508 {
512   - unsigned long flags;
513   - struct task_struct *g, *t;
  509 + struct task_struct *p, *t;
514 510  
515 511 sys_tracepoint_refcount--;
516 512 if (!sys_tracepoint_refcount) {
517   - read_lock_irqsave(&tasklist_lock, flags);
518   - do_each_thread(g, t) {
  513 + read_lock(&tasklist_lock);
  514 + for_each_process_thread(p, t) {
519 515 clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
520   - } while_each_thread(g, t);
521   - read_unlock_irqrestore(&tasklist_lock, flags);
  516 + }
  517 + read_unlock(&tasklist_lock);
522 518 }
523 519 }
524 520 #endif
samples/trace_events/trace-events-sample.h
... ... @@ -56,7 +56,8 @@
56 56 * struct: This defines the way the data will be stored in the ring buffer.
57 57 * There are currently two types of elements. __field and __array.
58 58 * a __field is broken up into (type, name). Where type can be any
59   - * type but an array.
  59 + * primitive type (integer, long or pointer). __field_struct() can
  60 + * be any static complex data value (struct, union, but not an array).
60 61 * For an array. there are three fields. (type, name, size). The
61 62 * type of elements in the array, the name of the field and the size
62 63 * of the array.