From: Oleg Nesterov <oleg@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Kirill Tkhai <ktkhai@parallels.com>,
linux-kernel@vger.kernel.org, Ingo Molnar <mingo@redhat.com>,
Vladimir Davydov <vdavydov@parallels.com>,
Kirill Tkhai <tkhai@yandex.ru>, Christoph Lameter <cl@linux.com>
Subject: Re: [PATCH 3/3] introduce task_rcu_dereference()
Date: Wed, 18 May 2016 21:57:33 +0200 [thread overview]
Message-ID: <20160518195733.GA15914@redhat.com> (raw)
In-Reply-To: <20160518191045.GP3193@twins.programming.kicks-ass.net>
On 05/18, Peter Zijlstra wrote:
>
> OK, something like so then?
Yes thanks!
Just one note,
> +struct task_struct *task_rcu_dereference(struct task_struct **ptask)
> +{
> + struct sighand_struct *sighand;
> + struct task_struct *task;
> +
> + /*
> + * We need to verify that release_task() was not called and thus
> + * delayed_put_task_struct() can't run and drop the last reference
> + * before rcu_read_unlock(). We check task->sighand != NULL,
> + * but we can read the already freed and reused memory.
> + */
> +retry:
> + task = rcu_dereference(*ptask);
> + if (!task)
> + return NULL;
> +
> + probe_kernel_address(&task->sighand, sighand);
OK. Then I'll re-send the patch which adds the probe_slab_address() helper
on top of this change. We do not want __probe_kernel_read() if
if CONFIG_DEBUG_PAGEALLOC=n.
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -1374,30 +1374,15 @@ static void task_numa_compare(struct task_numa_env *env,
> int dist = env->dist;
> bool assigned = false;
>
> - rcu_read_lock();
> -
> - raw_spin_lock_irq(&dst_rq->lock);
> - cur = dst_rq->curr;
> - /*
> - * No need to move the exiting task or idle task.
> - */
> - if ((cur->flags & PF_EXITING) || is_idle_task(cur))
> - cur = NULL;
> - else {
> - /*
> - * The task_struct must be protected here to protect the
> - * p->numa_faults access in the task_weight since the
> - * numa_faults could already be freed in the following path:
> - * finish_task_switch()
> - * --> put_task_struct()
> - * --> __put_task_struct()
> - * --> task_numa_free()
> - */
> - get_task_struct(cur);
> + cur = try_get_task_struct(&dst_rq->curr);
Do we really want try_get_task_struct() here? How about the change below?
To me it would be more clean to do get_task_struct() in task_numa_assign(),
it clearly pairs with put_task_struct(best_task) and task_numa_compare()
looks a bit simpler this way, no need to put_task_struct() if we nullify
cur.
What do you think? In any case I think the change in sched/fair.c should
probably come as a separate patch, but this is up to you.
Oleg.
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 40748dc..8e7083e 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1254,6 +1254,8 @@ static void task_numa_assign(struct task_numa_env *env,
{
if (env->best_task)
put_task_struct(env->best_task);
+ if (p)
+ get_task_struct(p);
env->best_task = p;
env->best_imp = imp;
@@ -1321,31 +1323,11 @@ static void task_numa_compare(struct task_numa_env *env,
long imp = env->p->numa_group ? groupimp : taskimp;
long moveimp = imp;
int dist = env->dist;
- bool assigned = false;
rcu_read_lock();
-
- raw_spin_lock_irq(&dst_rq->lock);
- cur = dst_rq->curr;
- /*
- * No need to move the exiting task or idle task.
- */
- if ((cur->flags & PF_EXITING) || is_idle_task(cur))
+ cur = task_rcu_dereference(&dst_rq->curr);
+ if (cur && ((cur->flags & PF_EXITING) || is_idle_task(cur)))
cur = NULL;
- else {
- /*
- * The task_struct must be protected here to protect the
- * p->numa_faults access in the task_weight since the
- * numa_faults could already be freed in the following path:
- * finish_task_switch()
- * --> put_task_struct()
- * --> __put_task_struct()
- * --> task_numa_free()
- */
- get_task_struct(cur);
- }
-
- raw_spin_unlock_irq(&dst_rq->lock);
/*
* Because we have preemption enabled we can get migrated around and
@@ -1428,7 +1410,6 @@ balance:
*/
if (!load_too_imbalanced(src_load, dst_load, env)) {
imp = moveimp - 1;
- put_task_struct(cur);
cur = NULL;
goto assign;
}
@@ -1454,16 +1435,9 @@ balance:
env->dst_cpu = select_idle_sibling(env->p, env->dst_cpu);
assign:
- assigned = true;
task_numa_assign(env, cur, imp);
unlock:
rcu_read_unlock();
- /*
- * The dst_rq->curr isn't assigned. The protection for task_struct is
- * finished.
- */
- if (cur && !assigned)
- put_task_struct(cur);
}
static void task_numa_find_cpu(struct task_numa_env *env,
next prev parent reply other threads:[~2016-05-18 19:57 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-22 7:17 [PATCH v4] sched/numa: fix unsafe get_task_struct() in task_numa_assign() Kirill Tkhai
2014-10-22 21:30 ` introduce task_rcu_dereference? Oleg Nesterov
2014-10-22 22:23 ` Oleg Nesterov
2014-10-23 18:15 ` Oleg Nesterov
2014-10-23 8:10 ` Kirill Tkhai
2014-10-23 18:18 ` Oleg Nesterov
2014-10-24 7:51 ` Kirill Tkhai
2014-10-27 19:53 ` [PATCH 0/3] introduce task_rcu_dereference() Oleg Nesterov
2014-10-27 19:54 ` [PATCH 1/3] probe_kernel_address() can use __probe_kernel_read() Oleg Nesterov
2014-10-27 19:54 ` [PATCH 2/3] introduce probe_slab_address() Oleg Nesterov
2014-10-27 19:21 ` Christoph Lameter
2014-10-28 5:44 ` Kirill Tkhai
2014-10-28 5:48 ` Kirill Tkhai
2014-10-28 15:01 ` Peter Zijlstra
2014-10-28 17:56 ` Kirill Tkhai
2014-10-28 18:00 ` Kirill Tkhai
2014-10-28 19:55 ` Oleg Nesterov
2014-10-28 20:12 ` Oleg Nesterov
2014-10-29 5:10 ` Kirill Tkhai
2014-10-27 19:54 ` [PATCH 3/3] introduce task_rcu_dereference() Oleg Nesterov
2014-10-28 6:22 ` Kirill Tkhai
2016-05-18 17:02 ` Peter Zijlstra
2016-05-18 18:23 ` Oleg Nesterov
2016-05-18 19:10 ` Peter Zijlstra
2016-05-18 19:57 ` Oleg Nesterov [this message]
2016-05-26 11:34 ` Peter Zijlstra
2016-06-03 10:49 ` [tip:sched/core] sched/fair: Use task_rcu_dereference() tip-bot for Oleg Nesterov
2016-06-03 10:48 ` [tip:sched/core] sched/api: Introduce task_rcu_dereference() and try_get_task_struct() tip-bot for Oleg Nesterov
2014-10-28 11:02 ` [tip:sched/core] sched/numa: Fix unsafe get_task_struct() in task_numa_assign() tip-bot for Kirill Tkhai
2014-11-08 3:48 ` [PATCH v4] sched/numa: fix " Sasha Levin
2014-11-09 14:07 ` Kirill Tkhai
2014-11-10 10:03 ` Peter Zijlstra
2014-11-10 15:48 ` Sasha Levin
2014-11-10 16:01 ` Peter Zijlstra
2014-11-16 9:50 ` [tip:sched/urgent] sched/numa: Avoid selecting oneself as swap target tip-bot for Peter Zijlstra
2014-11-10 16:03 ` [PATCH v4] sched/numa: fix unsafe get_task_struct() in task_numa_assign() Peter Zijlstra
2014-11-10 16:09 ` Sasha Levin
2014-11-10 16:16 ` Peter Zijlstra
2014-11-10 16:10 ` Kirill Tkhai
2014-11-10 16:36 ` Kirill Tkhai
2014-11-10 16:44 ` Sasha Levin
2014-11-10 20:01 ` Kirill Tkhai
2014-11-12 9:49 ` Kirill Tkhai
2014-11-15 2:38 ` Sasha Levin
2014-11-18 17:30 ` Sasha Levin
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=20160518195733.GA15914@redhat.com \
--to=oleg@redhat.com \
--cc=cl@linux.com \
--cc=ktkhai@parallels.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tkhai@yandex.ru \
--cc=vdavydov@parallels.com \
/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.