1 From a3d4f3b2dfafa2cd9e79fdf35ce8b2afef0fcd66 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Tue, 31 May 2011 16:59:16 +0200
4 Subject: [PATCH 088/365] sched: Move task_struct cleanup to RCU
6 __put_task_struct() does quite some expensive work. We don't want to
7 burden random tasks with that.
9 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
11 include/linux/sched.h | 13 +++++++++++++
12 kernel/fork.c | 15 ++++++++++++++-
13 2 files changed, 27 insertions(+), 1 deletion(-)
15 diff --git a/include/linux/sched.h b/include/linux/sched.h
16 index 4228b42..8f75cbb 100644
17 --- a/include/linux/sched.h
18 +++ b/include/linux/sched.h
19 @@ -1843,6 +1843,9 @@ struct task_struct {
20 unsigned int sequential_io;
21 unsigned int sequential_io_avg;
23 +#ifdef CONFIG_PREEMPT_RT_BASE
24 + struct rcu_head put_rcu;
26 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
27 unsigned long task_state_change;
29 @@ -2052,6 +2055,15 @@ extern struct pid *cad_pid;
30 extern void free_task(struct task_struct *tsk);
31 #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
33 +#ifdef CONFIG_PREEMPT_RT_BASE
34 +extern void __put_task_struct_cb(struct rcu_head *rhp);
36 +static inline void put_task_struct(struct task_struct *t)
38 + if (atomic_dec_and_test(&t->usage))
39 + call_rcu(&t->put_rcu, __put_task_struct_cb);
42 extern void __put_task_struct(struct task_struct *t);
44 static inline void put_task_struct(struct task_struct *t)
45 @@ -2059,6 +2071,7 @@ static inline void put_task_struct(struct task_struct *t)
46 if (atomic_dec_and_test(&t->usage))
51 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
52 extern void task_cputime(struct task_struct *t,
53 diff --git a/kernel/fork.c b/kernel/fork.c
54 index 06523cd..a94dde7 100644
57 @@ -244,7 +244,9 @@ static inline void put_signal_struct(struct signal_struct *sig)
58 if (atomic_dec_and_test(&sig->sigcnt))
59 free_signal_struct(sig);
62 +#ifdef CONFIG_PREEMPT_RT_BASE
65 void __put_task_struct(struct task_struct *tsk)
67 WARN_ON(!tsk->exit_state);
68 @@ -261,7 +263,18 @@ void __put_task_struct(struct task_struct *tsk)
69 if (!profile_handoff_task(tsk))
72 +#ifndef CONFIG_PREEMPT_RT_BASE
73 EXPORT_SYMBOL_GPL(__put_task_struct);
75 +void __put_task_struct_cb(struct rcu_head *rhp)
77 + struct task_struct *tsk = container_of(rhp, struct task_struct, put_rcu);
79 + __put_task_struct(tsk);
82 +EXPORT_SYMBOL_GPL(__put_task_struct_cb);
85 void __init __weak arch_task_cache_init(void) { }