All of lore.kernel.org
 help / color / mirror / Atom feed
* [for-next][PATCH v2 0/3] tracing: Fixes to syscall tracing
@ 2014-06-20 10:45 Steven Rostedt
  2014-06-20 10:45 ` [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race Steven Rostedt
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Steven Rostedt @ 2014-06-20 10:45 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov

I don't like to do this but I rebased my for-next branch to have
the first (for stable) patch not break other archs. This set passed my
cross compile test as well as my normal tests.

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next

Head SHA1: 0f6af1fe54b371ab6dfc05d963c0356a43c83226


Oleg Nesterov (3):
      tracing: Fix syscall_*regfunc() vs copy_process() race
      tracing: Change syscall_*regfunc() to check PF_KTHREAD and use for_each_process_thread()
      tracing: syscall_regfunc() should not skip kernel threads

----
 include/trace/syscall.h | 15 +++++++++++++++
 kernel/fork.c           |  2 ++
 kernel/tracepoint.c     | 26 +++++++++++---------------
 3 files changed, 28 insertions(+), 15 deletions(-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race
  2014-06-20 10:45 [for-next][PATCH v2 0/3] tracing: Fixes to syscall tracing Steven Rostedt
@ 2014-06-20 10:45 ` Steven Rostedt
  2014-06-21  1:11   ` Paul E. McKenney
  2014-06-24  6:55   ` Namhyung Kim
  2014-06-20 10:45 ` [for-next][PATCH v2 2/3] tracing: Change syscall_*regfunc() to check PF_KTHREAD and use for_each_process_thread() Steven Rostedt
  2014-06-20 10:45 ` [for-next][PATCH v2 3/3] tracing: syscall_regfunc() should not skip kernel threads Steven Rostedt
  2 siblings, 2 replies; 8+ messages in thread
From: Steven Rostedt @ 2014-06-20 10:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov, Frederic Weisbecker

[-- Attachment #1: 0001-tracing-Fix-syscall_-regfunc-vs-copy_process-race.patch --]
[-- Type: text/plain, Size: 2066 bytes --]

From: Oleg Nesterov <oleg@redhat.com>

syscall_regfunc() and syscall_unregfunc() should set/clear
TIF_SYSCALL_TRACEPOINT system-wide, but do_each_thread() can race
with copy_process() and miss the new child which was not added to
the process/thread lists yet.

Change copy_process() to update the child's TIF_SYSCALL_TRACEPOINT
under tasklist.

Link: http://lkml.kernel.org/p/20140413185854.GB20668@redhat.com

Cc: stable@vger.kernel.org # 2.6.33
Fixes: a871bd33a6c0 "tracing: Add syscall tracepoints"
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/trace/syscall.h | 15 +++++++++++++++
 kernel/fork.c           |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index fed853f3d7aa..9674145e2f6a 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -4,6 +4,7 @@
 #include <linux/tracepoint.h>
 #include <linux/unistd.h>
 #include <linux/ftrace_event.h>
+#include <linux/thread_info.h>
 
 #include <asm/ptrace.h>
 
@@ -32,4 +33,18 @@ struct syscall_metadata {
 	struct ftrace_event_call *exit_event;
 };
 
+#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
+		set_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+	else
+		clear_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
+}
+#else
+static inline void syscall_tracepoint_update(struct task_struct *p)
+{
+}
+#endif
+
 #endif /* _TRACE_SYSCALL_H */
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,
 
 	total_forks++;
 	spin_unlock(&current->sighand->siglock);
+	syscall_tracepoint_update(p);
 	write_unlock_irq(&tasklist_lock);
+
 	proc_fork_connector(p);
 	cgroup_post_fork(p);
 	if (clone_flags & CLONE_THREAD)
-- 
2.0.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [for-next][PATCH v2 2/3] tracing: Change syscall_*regfunc() to check PF_KTHREAD and use for_each_process_thread()
  2014-06-20 10:45 [for-next][PATCH v2 0/3] tracing: Fixes to syscall tracing Steven Rostedt
  2014-06-20 10:45 ` [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race Steven Rostedt
@ 2014-06-20 10:45 ` Steven Rostedt
  2014-06-20 10:45 ` [for-next][PATCH v2 3/3] tracing: syscall_regfunc() should not skip kernel threads Steven Rostedt
  2 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2014-06-20 10:45 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov

[-- Attachment #1: 0002-tracing-Change-syscall_-regfunc-to-check-PF_KTHREAD-.patch --]
[-- Type: text/plain, Size: 2117 bytes --]

From: Oleg Nesterov <oleg@redhat.com>

1. Remove _irqsafe from syscall_regfunc/syscall_unregfunc,
   read_lock(tasklist) doesn't need to disable irqs.

2. Change this code to avoid the deprecated do_each_thread()
   and use for_each_process_thread() (stolen from the patch
   from Frederic).

3. Change syscall_regfunc() to check PF_KTHREAD to skip
   the kernel threads, ->mm != NULL is the common mistake.

   Note: probably this check should be simply removed, needs
   another patch.

[fweisbec@gmail.com: s/do_each_thread/for_each_process_thread/]
Link: http://lkml.kernel.org/p/20140413185918.GC20668@redhat.com

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/tracepoint.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 33cbd8c203f8..9cf12640de5a 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -492,33 +492,31 @@ static int sys_tracepoint_refcount;
 
 void syscall_regfunc(void)
 {
-	unsigned long flags;
-	struct task_struct *g, *t;
+	struct task_struct *p, *t;
 
 	if (!sys_tracepoint_refcount) {
-		read_lock_irqsave(&tasklist_lock, flags);
-		do_each_thread(g, t) {
+		read_lock(&tasklist_lock);
+		for_each_process_thread(p, t) {
 			/* Skip kernel threads. */
-			if (t->mm)
+			if (!(t->flags & PF_KTHREAD))
 				set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
-		} while_each_thread(g, t);
-		read_unlock_irqrestore(&tasklist_lock, flags);
+		}
+		read_unlock(&tasklist_lock);
 	}
 	sys_tracepoint_refcount++;
 }
 
 void syscall_unregfunc(void)
 {
-	unsigned long flags;
-	struct task_struct *g, *t;
+	struct task_struct *p, *t;
 
 	sys_tracepoint_refcount--;
 	if (!sys_tracepoint_refcount) {
-		read_lock_irqsave(&tasklist_lock, flags);
-		do_each_thread(g, t) {
+		read_lock(&tasklist_lock);
+		for_each_process_thread(p, t) {
 			clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
-		} while_each_thread(g, t);
-		read_unlock_irqrestore(&tasklist_lock, flags);
+		}
+		read_unlock(&tasklist_lock);
 	}
 }
 #endif
-- 
2.0.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [for-next][PATCH v2 3/3] tracing: syscall_regfunc() should not skip kernel threads
  2014-06-20 10:45 [for-next][PATCH v2 0/3] tracing: Fixes to syscall tracing Steven Rostedt
  2014-06-20 10:45 ` [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race Steven Rostedt
  2014-06-20 10:45 ` [for-next][PATCH v2 2/3] tracing: Change syscall_*regfunc() to check PF_KTHREAD and use for_each_process_thread() Steven Rostedt
@ 2014-06-20 10:45 ` Steven Rostedt
  2 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2014-06-20 10:45 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Oleg Nesterov

[-- Attachment #1: 0003-tracing-syscall_regfunc-should-not-skip-kernel-threa.patch --]
[-- Type: text/plain, Size: 1548 bytes --]

From: Oleg Nesterov <oleg@redhat.com>

syscall_regfunc() ignores the kernel threads because "it has no effect",
see cc3b13c1 "Don't trace kernel thread syscalls" which added this check.

However, this means that a user-space task spawned by call_usermodehelper()
will run without TIF_SYSCALL_TRACEPOINT if sys_tracepoint_refcount != 0.

Remove this check. The unnecessary report from ret_from_fork path mentioned
by cc3b13c1 is no longer possible, see See commit fb45550d76bb5 "make sure
that kernel_thread() callbacks call do_exit() themselves".

A kernel_thread() callback can only return and take the int_ret_from_sys_call
path after do_execve() succeeds, otherwise the kernel will crash. But in this
case it is no longer a kernel thread and thus is needs TIF_SYSCALL_TRACEPOINT.

Link: http://lkml.kernel.org/p/20140413185938.GD20668@redhat.com

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
---
 kernel/tracepoint.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 9cf12640de5a..3490407dc7b7 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -497,9 +497,7 @@ void syscall_regfunc(void)
 	if (!sys_tracepoint_refcount) {
 		read_lock(&tasklist_lock);
 		for_each_process_thread(p, t) {
-			/* Skip kernel threads. */
-			if (!(t->flags & PF_KTHREAD))
-				set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
+			set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
 		}
 		read_unlock(&tasklist_lock);
 	}
-- 
2.0.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race
  2014-06-20 10:45 ` [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race Steven Rostedt
@ 2014-06-21  1:11   ` Paul E. McKenney
  2014-06-21  1:19     ` Steven Rostedt
  2014-06-24  6:55   ` Namhyung Kim
  1 sibling, 1 reply; 8+ messages in thread
From: Paul E. McKenney @ 2014-06-21  1:11 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Oleg Nesterov,
	Frederic Weisbecker

On Fri, Jun 20, 2014 at 06:45:19AM -0400, Steven Rostedt wrote:
> From: Oleg Nesterov <oleg@redhat.com>
> 
> syscall_regfunc() and syscall_unregfunc() should set/clear
> TIF_SYSCALL_TRACEPOINT system-wide, but do_each_thread() can race
> with copy_process() and miss the new child which was not added to
> the process/thread lists yet.
> 
> Change copy_process() to update the child's TIF_SYSCALL_TRACEPOINT
> under tasklist.
> 
> Link: http://lkml.kernel.org/p/20140413185854.GB20668@redhat.com
> 
> Cc: stable@vger.kernel.org # 2.6.33
> Fixes: a871bd33a6c0 "tracing: Add syscall tracepoints"
> Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

> ---
>  include/trace/syscall.h | 15 +++++++++++++++
>  kernel/fork.c           |  2 ++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/include/trace/syscall.h b/include/trace/syscall.h
> index fed853f3d7aa..9674145e2f6a 100644
> --- a/include/trace/syscall.h
> +++ b/include/trace/syscall.h
> @@ -4,6 +4,7 @@
>  #include <linux/tracepoint.h>
>  #include <linux/unistd.h>
>  #include <linux/ftrace_event.h>
> +#include <linux/thread_info.h>
>  
>  #include <asm/ptrace.h>
>  
> @@ -32,4 +33,18 @@ struct syscall_metadata {
>  	struct ftrace_event_call *exit_event;
>  };
>  
> +#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS)
> +static inline void syscall_tracepoint_update(struct task_struct *p)
> +{
> +	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
> +		set_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
> +	else
> +		clear_tsk_thread_flag(p, TIF_SYSCALL_TRACEPOINT);
> +}
> +#else
> +static inline void syscall_tracepoint_update(struct task_struct *p)
> +{
> +}
> +#endif
> +
>  #endif /* _TRACE_SYSCALL_H */
> 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,
>  
>  	total_forks++;
>  	spin_unlock(&current->sighand->siglock);
> +	syscall_tracepoint_update(p);
>  	write_unlock_irq(&tasklist_lock);
> +
>  	proc_fork_connector(p);
>  	cgroup_post_fork(p);
>  	if (clone_flags & CLONE_THREAD)
> -- 
> 2.0.0
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race
  2014-06-21  1:11   ` Paul E. McKenney
@ 2014-06-21  1:19     ` Steven Rostedt
  0 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2014-06-21  1:19 UTC (permalink / raw)
  To: paulmck
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Oleg Nesterov,
	Frederic Weisbecker

On Fri, 20 Jun 2014 18:11:25 -0700
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com> wrote:

> On Fri, Jun 20, 2014 at 06:45:19AM -0400, Steven Rostedt wrote:
> > From: Oleg Nesterov <oleg@redhat.com>
> > 
> > syscall_regfunc() and syscall_unregfunc() should set/clear
> > TIF_SYSCALL_TRACEPOINT system-wide, but do_each_thread() can race
> > with copy_process() and miss the new child which was not added to
> > the process/thread lists yet.
> > 
> > Change copy_process() to update the child's TIF_SYSCALL_TRACEPOINT
> > under tasklist.
> > 
> > Link: http://lkml.kernel.org/p/20140413185854.GB20668@redhat.com
> > 
> > Cc: stable@vger.kernel.org # 2.6.33
> > Fixes: a871bd33a6c0 "tracing: Add syscall tracepoints"
> > Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
> > Signed-off-by: Oleg Nesterov <oleg@redhat.com>
> > Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
> 
> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> 

I don't usually rebase my for-next branch for acks, but I already
rebased once for fixing an issue, and it's early in the rc cycle, and
this is the first patch on the branch, so I think I will do it.

Thanks!

-- Steve

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race
  2014-06-20 10:45 ` [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race Steven Rostedt
  2014-06-21  1:11   ` Paul E. McKenney
@ 2014-06-24  6:55   ` Namhyung Kim
  2014-06-26 17:49     ` Steven Rostedt
  1 sibling, 1 reply; 8+ messages in thread
From: Namhyung Kim @ 2014-06-24  6:55 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Oleg Nesterov,
	Frederic Weisbecker

Hi Steve,

On Fri, 20 Jun 2014 06:45:19 -0400, Steven Rostedt wrote:
> From: Oleg Nesterov <oleg@redhat.com>
>
> syscall_regfunc() and syscall_unregfunc() should set/clear
> TIF_SYSCALL_TRACEPOINT system-wide, but do_each_thread() can race
> with copy_process() and miss the new child which was not added to
> the process/thread lists yet.
>
> Change copy_process() to update the child's TIF_SYSCALL_TRACEPOINT
> under tasklist.

s/tasklist/tasklist_lock/ ?

Probably I'm too late..

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race
  2014-06-24  6:55   ` Namhyung Kim
@ 2014-06-26 17:49     ` Steven Rostedt
  0 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2014-06-26 17:49 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Oleg Nesterov,
	Frederic Weisbecker

On Tue, 24 Jun 2014 15:55:41 +0900
Namhyung Kim <namhyung@kernel.org> wrote:

> Hi Steve,
> 
> On Fri, 20 Jun 2014 06:45:19 -0400, Steven Rostedt wrote:
> > From: Oleg Nesterov <oleg@redhat.com>
> >
> > syscall_regfunc() and syscall_unregfunc() should set/clear
> > TIF_SYSCALL_TRACEPOINT system-wide, but do_each_thread() can race
> > with copy_process() and miss the new child which was not added to
> > the process/thread lists yet.
> >
> > Change copy_process() to update the child's TIF_SYSCALL_TRACEPOINT
> > under tasklist.
> 
> s/tasklist/tasklist_lock/ ?
> 
> Probably I'm too late..

Yeah, but it's just a change log, and I think people can figure it out
(I hope).

-- Steve

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-06-26 17:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-20 10:45 [for-next][PATCH v2 0/3] tracing: Fixes to syscall tracing Steven Rostedt
2014-06-20 10:45 ` [for-next][PATCH v2 1/3] tracing: Fix syscall_*regfunc() vs copy_process() race Steven Rostedt
2014-06-21  1:11   ` Paul E. McKenney
2014-06-21  1:19     ` Steven Rostedt
2014-06-24  6:55   ` Namhyung Kim
2014-06-26 17:49     ` Steven Rostedt
2014-06-20 10:45 ` [for-next][PATCH v2 2/3] tracing: Change syscall_*regfunc() to check PF_KTHREAD and use for_each_process_thread() Steven Rostedt
2014-06-20 10:45 ` [for-next][PATCH v2 3/3] tracing: syscall_regfunc() should not skip kernel threads Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.