提交 e0eead37 编写于 作者: E Eric W. Biederman 提交者: Yang Yingliang

tasks: Add a count of task RCU users

mainline inclusion
from mainline-5.4-rc1
commit 3fbd7ee2
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I3UKOW
CVE: NA

-------------------------------------------------

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: NLinus Torvalds <torvalds@linux-foundation.org>
Inspired-by: NOleg Nesterov <oleg@redhat.com>
Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Chris Metcalf <cmetcalf@ezchip.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Kirill Tkhai <tkhai@yandex.ru>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Russell King - ARM Linux admin <linux@armlinux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/87woebdplt.fsf_-_@x220.int.ebiederm.orgSigned-off-by: NIngo Molnar <mingo@kernel.org>
Signed-off-by: NLi Hua <hucool.lihua@huawei.com>
Signed-off-by: NZheng Zucheng <zhengzucheng@huawei.com>

 Conflicts:
         kernel/fork.c
Reviewed-by: NCheng Jian <cj.chengjian@huawei.com>
Reviewed-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 42a3fca0
......@@ -1087,7 +1087,10 @@ struct task_struct {
struct tlbflush_unmap_batch tlb_ubc;
union {
refcount_t rcu_users;
struct rcu_head rcu;
};
/* Cache last used pipe for splice(): */
struct pipe_inode_info *splice_pipe;
......
......@@ -106,6 +106,7 @@ static inline void put_task_struct_many(struct task_struct *t, int nr)
}
struct task_struct *task_rcu_dereference(struct task_struct **ptask);
void put_task_struct_rcu_user(struct task_struct *task);
#ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT
extern int arch_task_struct_size __read_mostly;
......
......@@ -172,6 +172,11 @@ static void delayed_put_task_struct(struct rcu_head *rhp)
put_task_struct(tsk);
}
void put_task_struct_rcu_user(struct task_struct *task)
{
if (refcount_dec_and_test(&task->rcu_users))
call_rcu(&task->rcu, delayed_put_task_struct);
}
void release_task(struct task_struct *p)
{
......@@ -212,7 +217,7 @@ void release_task(struct task_struct *p)
write_unlock_irq(&tasklist_lock);
release_thread(p);
call_rcu(&p->rcu, delayed_put_task_struct);
put_task_struct_rcu_user(p);
p = leader;
if (unlikely(zap_leader))
......
......@@ -896,10 +896,9 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
tsk->stack_canary = get_random_canary();
#endif
/*
* One for us, one for whoever does the "release_task()" (usually
* parent)
*/
/* One for the user space visible state that goes away when reaped. */
refcount_set(&tsk->rcu_users, 1);
/* One for the rcu users, and one for the scheduler */
atomic_set(&tsk->usage, 2);
#ifdef CONFIG_BLK_DEV_IO_TRACE
tsk->btrace_seq = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册