diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-25 08:08:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-25 08:08:09 -0400 |
commit | b8e46d22dc7cb66c70aeec57fff6101dbd96f30d (patch) | |
tree | 45a2aa94a184583d68f3ccc462683bb9b50d71c1 /kernel | |
parent | 10b5b5361a3c2a7fff9dbfa0f127adc2531e7732 (diff) | |
parent | 4d4c9cc839a308be3289a361ccba4447ee140552 (diff) |
Merge tag 'trace-fixes-v3.16-rc1-v2' of git://git.kernel.org/pub/scm/linux/kernel/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
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fork.c | 2 | ||||
-rw-r--r-- | kernel/tracepoint.c | 26 |
2 files changed, 13 insertions, 15 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index d2799d1fc952..6a13c46cd87d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1487,7 +1487,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1487 | 1487 | ||
1488 | total_forks++; | 1488 | total_forks++; |
1489 | spin_unlock(¤t->sighand->siglock); | 1489 | spin_unlock(¤t->sighand->siglock); |
1490 | syscall_tracepoint_update(p); | ||
1490 | write_unlock_irq(&tasklist_lock); | 1491 | write_unlock_irq(&tasklist_lock); |
1492 | |||
1491 | proc_fork_connector(p); | 1493 | proc_fork_connector(p); |
1492 | cgroup_post_fork(p); | 1494 | cgroup_post_fork(p); |
1493 | if (clone_flags & CLONE_THREAD) | 1495 | if (clone_flags & CLONE_THREAD) |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 33cbd8c203f8..3490407dc7b7 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
@@ -492,33 +492,29 @@ static int sys_tracepoint_refcount; | |||
492 | 492 | ||
493 | void syscall_regfunc(void) | 493 | void syscall_regfunc(void) |
494 | { | 494 | { |
495 | unsigned long flags; | 495 | struct task_struct *p, *t; |
496 | struct task_struct *g, *t; | ||
497 | 496 | ||
498 | if (!sys_tracepoint_refcount) { | 497 | if (!sys_tracepoint_refcount) { |
499 | read_lock_irqsave(&tasklist_lock, flags); | 498 | read_lock(&tasklist_lock); |
500 | do_each_thread(g, t) { | 499 | for_each_process_thread(p, t) { |
501 | /* Skip kernel threads. */ | 500 | set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT); |
502 | if (t->mm) | 501 | } |
503 | set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT); | 502 | read_unlock(&tasklist_lock); |
504 | } while_each_thread(g, t); | ||
505 | read_unlock_irqrestore(&tasklist_lock, flags); | ||
506 | } | 503 | } |
507 | sys_tracepoint_refcount++; | 504 | sys_tracepoint_refcount++; |
508 | } | 505 | } |
509 | 506 | ||
510 | void syscall_unregfunc(void) | 507 | void syscall_unregfunc(void) |
511 | { | 508 | { |
512 | unsigned long flags; | 509 | struct task_struct *p, *t; |
513 | struct task_struct *g, *t; | ||
514 | 510 | ||
515 | sys_tracepoint_refcount--; | 511 | sys_tracepoint_refcount--; |
516 | if (!sys_tracepoint_refcount) { | 512 | if (!sys_tracepoint_refcount) { |
517 | read_lock_irqsave(&tasklist_lock, flags); | 513 | read_lock(&tasklist_lock); |
518 | do_each_thread(g, t) { | 514 | for_each_process_thread(p, t) { |
519 | clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT); | 515 | clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT); |
520 | } while_each_thread(g, t); | 516 | } |
521 | read_unlock_irqrestore(&tasklist_lock, flags); | 517 | read_unlock(&tasklist_lock); |
522 | } | 518 | } |
523 | } | 519 | } |
524 | #endif | 520 | #endif |