[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190904144415.GB20391@lenoir>
Date: Wed, 4 Sep 2019 16:44:16 +0200
From: Frederic Weisbecker <frederic@...nel.org>
To: "Eric W. Biederman" <ebiederm@...ssion.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
Oleg Nesterov <oleg@...hat.com>,
Russell King - ARM Linux admin <linux@...linux.org.uk>,
Peter Zijlstra <peterz@...radead.org>,
Chris Metcalf <cmetcalf@...hip.com>,
Christoph Lameter <cl@...ux.com>,
Kirill Tkhai <tkhai@...dex.ru>, Mike Galbraith <efault@....de>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...nel.org>,
Linux List Kernel Mailing <linux-kernel@...r.kernel.org>,
Davidlohr Bueso <dave@...olabs.net>
Subject: Re: [PATCH 1/3] task: Add a count of task rcu users
On Mon, Sep 02, 2019 at 11:51:34PM -0500, Eric W. Biederman wrote:
>
> Add a count of the number of rcu users (currently 1) of the task
> struct so that we can later add the scheduler case and get rid of the
> very subtle task_rcu_dereference, and just use rcu_dereference.
>
> As suggested by Oleg have the count overlap rcu_head so that no
> additional space in task_struct is required.
>
> Inspired-by: Linus Torvalds <torvalds@...ux-foundation.org>
> Inspired-by: Oleg Nesterov <oleg@...hat.com>
> Signed-off-by: "Eric W. Biederman" <ebiederm@...ssion.com>
> ---
> include/linux/sched.h | 5 ++++-
> include/linux/sched/task.h | 1 +
> kernel/exit.c | 7 ++++++-
> kernel/fork.c | 7 +++----
> 4 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 9f51932bd543..99a4518b9b17 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1142,7 +1142,10 @@ struct task_struct {
>
> struct tlbflush_unmap_batch tlb_ubc;
>
> - struct rcu_head rcu;
> + union {
> + refcount_t rcu_users;
> + struct rcu_head rcu;
So what happens if, say:
CPU 1 CPU 2
--------------------------------------------------------------
rcu_read_lock()
p = rcu_dereference(rq->task)
if (refcount_inc_not_zero(p->rcu_users)) {
.....
release_task() {
put_task_struct_rcu_user() {
call_rcu() {
queue rcu_head
}
}
}
put_task_struct_rcu_user(); //here rcu_users has been overwritten
Thanks.
Powered by blists - more mailing lists