aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/delayacct.c
diff options
context:
space:
mode:
authorShailabh Nagar <nagar@watson.ibm.com>2006-09-01 00:27:38 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-01 14:39:08 -0400
commit35df17c57cecb08f0120fb18926325f1093dc429 (patch)
treedc79780b3133e55dc591e35238fdb313e8e0219e /kernel/delayacct.c
parent30f3174d1c506db2c6d2c1dddc9c064e741d6b76 (diff)
[PATCH] task delay accounting fixes
Cleanup allocation and freeing of tsk->delays used by delay accounting. This solves two problems reported for delay accounting: 1. oops in __delayacct_blkio_ticks http://www.uwsg.indiana.edu/hypermail/linux/kernel/0608.2/1844.html Currently tsk->delays is getting freed too early in task exit which can cause a NULL tsk->delays to get accessed via reading of /proc/<tgid>/stats. The patch fixes this problem by freeing tsk->delays closer to when task_struct itself is freed up. As a result, it also eliminates the use of tsk->delays_lock which was only being used (inadequately) to safeguard access to tsk->delays while a task was exiting. 2. Possible memory leak in kernel/delayacct.c http://www.uwsg.indiana.edu/hypermail/linux/kernel/0608.2/1389.html The patch cleans up tsk->delays allocations after a bad fork which was missing earlier. The patch has been tested to fix the problems listed above and stress tested with rapid calls to delay accounting's taskstats command interface (which is the other path that can access the same data, besides the /proc interface causing the oops above). Signed-off-by: Shailabh Nagar <nagar@watson.ibm.com> Cc: Balbir Singh <balbir@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/delayacct.c')
-rw-r--r--kernel/delayacct.c16
1 files changed, 0 insertions, 16 deletions
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