All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleg Nesterov <oleg@redhat.com>
To: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Ingo Molnar <mingo@elte.hu>,
	Alan Stern <stern@rowland.harvard.edu>,
	Arnaldo Carvalho de Melo <acme@redhat.com>,
	Paul Mackerras <paulus@samba.org>,
	Prasad <prasad@linux.vnet.ibm.com>,
	Roland McGrath <roland@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: Re: Q: perf_install_in_context/perf_event_enable are racy?
Date: Wed, 26 Jan 2011 18:53:22 +0100	[thread overview]
Message-ID: <20110126175322.GA28617@redhat.com> (raw)
In-Reply-To: <20110124114234.GA12166@redhat.com>

On 01/24, Oleg Nesterov wrote:
>
> Frederic, All, can't we simplify this?

Well, to clarify, it looks simpler to me ;)

But if you don't like this approach, lets use task_events_schedulable flag.

> First, we modify __perf_install_in_context() so that it never tries
> to install the event into !is_active context. IOW, it never tries
> to set cpuctx->task_ctx = ctx.
>
> Then we add the new trivial helper stop_resched_task(task) which
> simply wakeups the stop thread on task_cpu(task), and thus forces
> this task to reschedule.
>
> ...
>
> Yes, stop_resched_task() can't help if this task itself is the stop thread.
> But the stop thread shouldn't run for a long time without rescheduling,
> otherwise we already have the problems.

Please see the untested patch below. It doesn't change perf_event_enable(),
only perf_install_in_context(). Just for early review to know your opinion.
To simplify the reading, here is the code:

	void task_force_schedule(struct task_struct *p)
	{
		struct rq *rq;

		preempt_disable();
		rq = task_rq(p);
		if (rq->curr == p)
			wake_up_process(rq->stop);
		preempt_enable();
	}

	static void
	perf_install_in_context(struct perf_event_context *ctx,
				struct perf_event *event,
				int cpu)
	{
		struct task_struct *task = ctx->task;

		event->ctx = ctx;

		if (!task) {
			/*
			 * Per cpu events are installed via an smp call and
			 * the install is always successful.
			 */
			smp_call_function_single(cpu, __perf_install_in_context,
						 event, 1);
			return;
		}

		for (;;) {
			raw_spin_lock_irq(&ctx->lock);
			/*
			 * The lock prevents that this context is
			 * scheduled in, we can add the event safely.
			 */
			if (!ctx->is_active)
				add_event_to_ctx(event, ctx);
			raw_spin_unlock_irq(&ctx->lock);

			if (event->attach_state & PERF_ATTACH_CONTEXT) {
				task_force_schedule(task);
				break;
			}

			task_oncpu_function_call(task, __perf_install_in_context,
							event);
			if (event->attach_state & PERF_ATTACH_CONTEXT)
				break;
		}
	}

Oleg.

 include/linux/sched.h |    1 +
 kernel/sched.c        |   11 +++++++++++
 kernel/perf_event.c   |   49 +++++++++++++++++++++----------------------------
 3 files changed, 33 insertions(+), 28 deletions(-)

--- perf/include/linux/sched.h~1_force_resched	2011-01-14 18:21:04.000000000 +0100
+++ perf/include/linux/sched.h	2011-01-26 17:54:28.000000000 +0100
@@ -2584,6 +2584,7 @@ static inline void inc_syscw(struct task
 extern void task_oncpu_function_call(struct task_struct *p,
 				     void (*func) (void *info), void *info);
 
+extern void task_force_schedule(struct task_struct *p);
 
 #ifdef CONFIG_MM_OWNER
 extern void mm_update_next_owner(struct mm_struct *mm);
--- perf/kernel/sched.c~1_force_resched	2011-01-20 20:37:11.000000000 +0100
+++ perf/kernel/sched.c	2011-01-26 17:52:42.000000000 +0100
@@ -1968,6 +1968,17 @@ void sched_set_stop_task(int cpu, struct
 	}
 }
 
+void task_force_schedule(struct task_struct *p)
+{
+	struct rq *rq;
+
+	preempt_disable();
+	rq = task_rq(p);
+	if (rq->curr == p)
+		wake_up_process(rq->stop);
+	preempt_enable();
+}
+
 /*
  * __normal_prio - return the priority that is based on the static prio
  */
--- perf/kernel/perf_event.c~2_install_ctx_via_resched	2011-01-21 18:41:02.000000000 +0100
+++ perf/kernel/perf_event.c	2011-01-26 18:32:30.000000000 +0100
@@ -943,16 +943,10 @@ static void __perf_install_in_context(vo
 
 	/*
 	 * If this is a task context, we need to check whether it is
-	 * the current task context of this cpu. If not it has been
-	 * scheduled out before the smp call arrived.
-	 * Or possibly this is the right context but it isn't
-	 * on this cpu because it had no events.
+	 * the current task context of this cpu.
 	 */
-	if (ctx->task && cpuctx->task_ctx != ctx) {
-		if (cpuctx->task_ctx || ctx->task != current)
-			return;
-		cpuctx->task_ctx = ctx;
-	}
+	if (ctx->task && cpuctx->task_ctx != ctx)
+		return;
 
 	raw_spin_lock(&ctx->lock);
 	ctx->is_active = 1;
@@ -1030,27 +1024,26 @@ perf_install_in_context(struct perf_even
 		return;
 	}
 
-retry:
-	task_oncpu_function_call(task, __perf_install_in_context,
-				 event);
-
-	raw_spin_lock_irq(&ctx->lock);
-	/*
-	 * we need to retry the smp call.
-	 */
-	if (ctx->is_active && list_empty(&event->group_entry)) {
+	for (;;) {
+		raw_spin_lock_irq(&ctx->lock);
+		/*
+		 * The lock prevents that this context is
+		 * scheduled in, we can add the event safely.
+		 */
+		if (!ctx->is_active)
+			add_event_to_ctx(event, ctx);
 		raw_spin_unlock_irq(&ctx->lock);
-		goto retry;
-	}
 
-	/*
-	 * The lock prevents that this context is scheduled in so we
-	 * can add the event safely, if it the call above did not
-	 * succeed.
-	 */
-	if (list_empty(&event->group_entry))
-		add_event_to_ctx(event, ctx);
-	raw_spin_unlock_irq(&ctx->lock);
+		if (event->attach_state & PERF_ATTACH_CONTEXT) {
+			task_force_schedule(task);
+			break;
+		}
+
+		task_oncpu_function_call(task, __perf_install_in_context,
+						event);
+		if (event->attach_state & PERF_ATTACH_CONTEXT)
+			break;
+	}
 }
 
 /*


  reply	other threads:[~2011-01-26 18:25 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-08 14:56 Q: perf_event && task->ptrace_bps[] Oleg Nesterov
2010-11-08 14:57 ` Q: sys_perf_event_open() && PF_EXITING Oleg Nesterov
2011-01-19 18:21   ` [PATCH 0/2] Was: " Oleg Nesterov
2011-01-19 18:22     ` [PATCH 1/2] perf: fix find_get_context() vs perf_event_exit_task() race Oleg Nesterov
2011-01-19 18:49       ` Peter Zijlstra
2011-01-19 19:18       ` [tip:perf/urgent] perf: Fix " tip-bot for Oleg Nesterov
2011-01-21 15:29         ` Ingo Molnar
2011-01-21 15:53           ` Oleg Nesterov
2011-01-21 17:45             ` [PATCH] perf: perf_event_exit_task_context: s/rcu_dereference/rcu_dereference_raw/ Oleg Nesterov
2011-01-21 17:53               ` Oleg Nesterov
2011-01-21 21:50                 ` Paul E. McKenney
2011-01-24 11:51                   ` Oleg Nesterov
2011-01-21 22:12               ` [tip:perf/urgent] " tip-bot for Oleg Nesterov
2011-01-19 18:22     ` [PATCH 2/2] perf: fix perf_event_init_task()/perf_event_free_task() interaction Oleg Nesterov
2011-01-19 18:51       ` Peter Zijlstra
2011-01-19 19:19       ` [tip:perf/urgent] perf: Fix " tip-bot for Oleg Nesterov
2011-01-20 19:30     ` Q: perf_install_in_context/perf_event_enable are racy? Oleg Nesterov
2011-01-21 12:11       ` Peter Zijlstra
2011-01-21 13:03         ` Ingo Molnar
2011-01-21 13:39           ` Peter Zijlstra
2011-01-21 14:26             ` Oleg Nesterov
2011-01-21 15:05               ` Peter Zijlstra
2011-01-21 20:40                 ` Frederic Weisbecker
2011-01-24 11:42                   ` Oleg Nesterov
2011-01-26 17:53                     ` Oleg Nesterov [this message]
2011-01-26 18:49                       ` Oleg Nesterov
2011-01-26 18:51                         ` [PATCH] fix the theoretical task_cpu/task_curr problem in kick_process/task_oncpu_function_call Oleg Nesterov
2011-01-26 19:05                         ` Q: perf_install_in_context/perf_event_enable are racy? Peter Zijlstra
2011-01-26 19:33                           ` Peter Zijlstra
2011-01-26 19:38                             ` Peter Zijlstra
2011-01-26 21:19                             ` Oleg Nesterov
2011-01-26 21:33                               ` Oleg Nesterov
2011-01-27 10:32                                 ` Peter Zijlstra
2011-01-27 12:29                                   ` Peter Zijlstra
2011-01-27 16:10                                     ` Oleg Nesterov
2011-01-27 16:27                                       ` Peter Zijlstra
2011-01-27 16:59                                         ` Oleg Nesterov
2011-01-27 15:52                                   ` Oleg Nesterov
2011-01-27 13:14                       ` Peter Zijlstra
2011-01-27 14:28                         ` Peter Zijlstra
2011-01-27 14:58                           ` Peter Zijlstra
2011-01-27 16:57                         ` Oleg Nesterov
2011-01-27 17:11                           ` Peter Zijlstra
2011-01-27 22:18                             ` Oleg Nesterov
2011-01-28 11:52                               ` Peter Zijlstra
2011-01-28 14:57                                 ` Peter Zijlstra
2011-01-28 16:28                                   ` Oleg Nesterov
2011-01-28 18:11                                     ` Peter Zijlstra
2011-01-31 17:26                                       ` Oleg Nesterov
2011-01-31 18:23                                         ` Peter Zijlstra
2011-01-31 19:11                                           ` Oleg Nesterov
2011-01-31 19:29                                             ` Peter Zijlstra
2011-02-01 14:03                                               ` [PATCH] perf: Cure task_oncpu_function_call() races Peter Zijlstra
2011-02-01 17:27                                                 ` Oleg Nesterov
2011-02-01 18:08                                                   ` Peter Zijlstra
2011-02-01 18:18                                                     ` Peter Zijlstra
2011-02-01 21:00                                                     ` Peter Zijlstra
2010-11-08 14:57 ` Q: perf_event && event->owner Oleg Nesterov
2010-11-08 20:11   ` Frederic Weisbecker
2010-11-08 20:41     ` Peter Zijlstra
2010-11-09 16:18       ` Oleg Nesterov
2010-11-09 15:57     ` Oleg Nesterov
2010-11-09 16:56       ` Peter Zijlstra
2010-11-09 16:58         ` Oleg Nesterov
2010-11-09 17:07           ` Peter Zijlstra
2010-11-09 17:42             ` Oleg Nesterov
2010-11-09 18:01               ` Peter Zijlstra
2010-11-09 18:57                 ` Oleg Nesterov
2010-11-09 19:16                   ` Peter Zijlstra
2010-11-10 15:17                   ` Peter Zijlstra
2010-11-10 15:44                     ` Oleg Nesterov
2010-11-12 15:48                       ` Peter Zijlstra
2010-11-12 18:49                         ` Oleg Nesterov
2010-11-18 14:09                         ` [tip:perf/urgent] perf: Fix owner-list vs exit tip-bot for Peter Zijlstra
2010-11-08 18:41 ` Q: perf_event && task->ptrace_bps[] Frederic Weisbecker
2010-11-08 19:18   ` Oleg Nesterov
2011-01-17 23:58     ` Frederic Weisbecker
2011-01-18  1:16       ` Roland McGrath
2011-01-17 20:34 ` Oleg Nesterov
2011-01-17 20:52   ` Peter Zijlstra
2011-01-17 21:01     ` Frederic Weisbecker
2011-01-18 16:09     ` [PATCH 0/2] perf: event->cpu checking fixes Oleg Nesterov
2011-01-18 16:10       ` [PATCH 1/2] perf: find_get_context: fix the per-cpu-counter check Oleg Nesterov
2011-01-18 19:06         ` [tip:perf/urgent] perf: Find_get_context: " tip-bot for Oleg Nesterov
2011-01-18 16:10       ` [PATCH 2/2] perf: validate cpu early in perf_event_alloc() Oleg Nesterov
2011-01-18 19:07         ` [tip:perf/urgent] perf: Validate " tip-bot for Oleg Nesterov
2011-01-18 18:42   ` Q: perf_event && task->ptrace_bps[] Frederic Weisbecker
2011-01-19 15:37     ` Oleg Nesterov
2011-01-19 20:05       ` Frederic Weisbecker
2011-01-20 17:28         ` Oleg Nesterov
2011-01-28 17:41           ` Frederic Weisbecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110126175322.GA28617@redhat.com \
    --to=oleg@redhat.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=acme@redhat.com \
    --cc=fweisbec@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=paulus@samba.org \
    --cc=prasad@linux.vnet.ibm.com \
    --cc=roland@redhat.com \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.