aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/delayacct.h10
-rw-r--r--include/linux/sched.h1
-rw-r--r--kernel/delayacct.c16
-rw-r--r--kernel/exit.c1
-rw-r--r--kernel/fork.c6
5 files changed, 11 insertions, 23 deletions
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
index 11487b6e7127..561e2a77805c 100644
--- a/include/linux/delayacct.h
+++ b/include/linux/delayacct.h
@@ -59,10 +59,14 @@ static inline void delayacct_tsk_init(struct task_struct *tsk)
59 __delayacct_tsk_init(tsk); 59 __delayacct_tsk_init(tsk);
60} 60}
61 61
62static inline void delayacct_tsk_exit(struct task_struct *tsk) 62/* Free tsk->delays. Called from bad fork and __put_task_struct
63 * where there's no risk of tsk->delays being accessed elsewhere
64 */
65static inline void delayacct_tsk_free(struct task_struct *tsk)
63{ 66{
64 if (tsk->delays) 67 if (tsk->delays)
65 __delayacct_tsk_exit(tsk); 68 kmem_cache_free(delayacct_cache, tsk->delays);
69 tsk->delays = NULL;
66} 70}
67 71
68static inline void delayacct_blkio_start(void) 72static inline void delayacct_blkio_start(void)
@@ -101,7 +105,7 @@ static inline void delayacct_init(void)
101{} 105{}
102static inline void delayacct_tsk_init(struct task_struct *tsk) 106static inline void delayacct_tsk_init(struct task_struct *tsk)
103{} 107{}
104static inline void delayacct_tsk_exit(struct task_struct *tsk) 108static inline void delayacct_tsk_free(struct task_struct *tsk)
105{} 109{}
106static inline void delayacct_blkio_start(void) 110static inline void delayacct_blkio_start(void)
107{} 111{}
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6674fc1e51bf..34ed0d99b1bd 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -994,7 +994,6 @@ struct task_struct {
994 */ 994 */
995 struct pipe_inode_info *splice_pipe; 995 struct pipe_inode_info *splice_pipe;
996#ifdef CONFIG_TASK_DELAY_ACCT 996#ifdef CONFIG_TASK_DELAY_ACCT
997 spinlock_t delays_lock;
998 struct task_delay_info *delays; 997 struct task_delay_info *delays;
999#endif 998#endif
1000}; 999};
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index 57ca3730205d..36752f124c6a 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -41,24 +41,11 @@ void delayacct_init(void)
41 41
42void __delayacct_tsk_init(struct task_struct *tsk) 42void __delayacct_tsk_init(struct task_struct *tsk)
43{ 43{
44 spin_lock_init(&tsk->delays_lock);
45 /* No need to acquire tsk->delays_lock for allocation here unless
46 __delayacct_tsk_init called after tsk is attached to tasklist
47 */
48 tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL); 44 tsk->delays = kmem_cache_zalloc(delayacct_cache, SLAB_KERNEL);
49 if (tsk->delays) 45 if (tsk->delays)
50 spin_lock_init(&tsk->delays->lock); 46 spin_lock_init(&tsk->delays->lock);
51} 47}
52 48
53void __delayacct_tsk_exit(struct task_struct *tsk)
54{
55 struct task_delay_info *delays = tsk->delays;
56 spin_lock(&tsk->delays_lock);
57 tsk->delays = NULL;
58 spin_unlock(&tsk->delays_lock);
59 kmem_cache_free(delayacct_cache, delays);
60}
61
62/* 49/*
63 * Start accounting for a delay statistic using 50 * Start accounting for a delay statistic using
64 * its starting timestamp (@start) 51 * its starting timestamp (@start)
@@ -118,8 +105,6 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
118 struct timespec ts; 105 struct timespec ts;
119 unsigned long t1,t2,t3; 106 unsigned long t1,t2,t3;
120 107
121 spin_lock(&tsk->delays_lock);
122
123 /* Though tsk->delays accessed later, early exit avoids 108 /* Though tsk->delays accessed later, early exit avoids
124 * unnecessary returning of other data 109 * unnecessary returning of other data
125 */ 110 */
@@ -161,7 +146,6 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
161 spin_unlock(&tsk->delays->lock); 146 spin_unlock(&tsk->delays->lock);
162 147
163done: 148done:
164 spin_unlock(&tsk->delays_lock);
165 return 0; 149 return 0;
166} 150}
167 151
diff --git a/kernel/exit.c b/kernel/exit.c
index dba194a8d416..a4c19a52ce46 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -908,7 +908,6 @@ fastcall NORET_TYPE void do_exit(long code)
908 audit_free(tsk); 908 audit_free(tsk);
909 taskstats_exit_send(tsk, tidstats, group_dead, mycpu); 909 taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
910 taskstats_exit_free(tidstats); 910 taskstats_exit_free(tidstats);
911 delayacct_tsk_exit(tsk);
912 911
913 exit_mm(tsk); 912 exit_mm(tsk);
914 913
diff --git a/kernel/fork.c b/kernel/fork.c
index aa36c43783cc..f9b014e3e700 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -117,6 +117,7 @@ void __put_task_struct(struct task_struct *tsk)
117 security_task_free(tsk); 117 security_task_free(tsk);
118 free_uid(tsk->user); 118 free_uid(tsk->user);
119 put_group_info(tsk->group_info); 119 put_group_info(tsk->group_info);
120 delayacct_tsk_free(tsk);
120 121
121 if (!profile_handoff_task(tsk)) 122 if (!profile_handoff_task(tsk))
122 free_task(tsk); 123 free_task(tsk);
@@ -1011,7 +1012,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1011 retval = -EFAULT; 1012 retval = -EFAULT;
1012 if (clone_flags & CLONE_PARENT_SETTID) 1013 if (clone_flags & CLONE_PARENT_SETTID)
1013 if (put_user(p->pid, parent_tidptr)) 1014 if (put_user(p->pid, parent_tidptr))
1014 goto bad_fork_cleanup; 1015 goto bad_fork_cleanup_delays_binfmt;
1015 1016
1016 INIT_LIST_HEAD(&p->children); 1017 INIT_LIST_HEAD(&p->children);
1017 INIT_LIST_HEAD(&p->sibling); 1018 INIT_LIST_HEAD(&p->sibling);
@@ -1277,7 +1278,8 @@ bad_fork_cleanup_policy:
1277bad_fork_cleanup_cpuset: 1278bad_fork_cleanup_cpuset:
1278#endif 1279#endif
1279 cpuset_exit(p); 1280 cpuset_exit(p);
1280bad_fork_cleanup: 1281bad_fork_cleanup_delays_binfmt:
1282 delayacct_tsk_free(p);
1281 if (p->binfmt) 1283 if (p->binfmt)
1282 module_put(p->binfmt->module); 1284 module_put(p->binfmt->module);
1283bad_fork_cleanup_put_domain: 1285bad_fork_cleanup_put_domain: