aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-06-26 03:26:01 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:26 -0400
commitcc288738c9ae3c64d3c50b86604044d1f6d22941 (patch)
tree87058616bfa84572647fbe574fe733e81c1d17b6 /fs/proc/base.c
parentdf26c40e567356caeefe2861311e19c54444d917 (diff)
[PATCH] proc: Remove tasklist_lock from proc_task_readdir.
This is just like my previous removal of tasklist_lock from first_tgid, and next_tgid. It simply had to wait until it was rcu safe to walk the thread list. This should be the last instance of the tasklist_lock in proc. So user processes should not be able to influence the tasklist lock hold times. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 773469703c62..6092a6e2c5a9 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2224,11 +2224,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2224 * In the case of a seek we start with the leader and walk nr 2224 * In the case of a seek we start with the leader and walk nr
2225 * threads past it. 2225 * threads past it.
2226 */ 2226 */
2227static struct task_struct *first_tid(struct task_struct *leader, int tid, int nr) 2227static struct task_struct *first_tid(struct task_struct *leader,
2228 int tid, int nr)
2228{ 2229{
2229 struct task_struct *pos = NULL; 2230 struct task_struct *pos = NULL;
2230 read_lock(&tasklist_lock);
2231 2231
2232 rcu_read_lock();
2232 /* Attempt to start with the pid of a thread */ 2233 /* Attempt to start with the pid of a thread */
2233 if (tid && (nr > 0)) { 2234 if (tid && (nr > 0)) {
2234 pos = find_task_by_pid(tid); 2235 pos = find_task_by_pid(tid);
@@ -2258,7 +2259,7 @@ static struct task_struct *first_tid(struct task_struct *leader, int tid, int nr
2258 } 2259 }
2259 pos = NULL; 2260 pos = NULL;
2260done: 2261done:
2261 read_unlock(&tasklist_lock); 2262 rcu_read_unlock();
2262 return pos; 2263 return pos;
2263} 2264}
2264 2265
@@ -2271,7 +2272,7 @@ done:
2271static struct task_struct *next_tid(struct task_struct *start) 2272static struct task_struct *next_tid(struct task_struct *start)
2272{ 2273{
2273 struct task_struct *pos; 2274 struct task_struct *pos;
2274 read_lock(&tasklist_lock); 2275 rcu_read_lock();
2275 pos = start; 2276 pos = start;
2276 if (pid_alive(start)) 2277 if (pid_alive(start))
2277 pos = next_thread(start); 2278 pos = next_thread(start);
@@ -2279,7 +2280,7 @@ static struct task_struct *next_tid(struct task_struct *start)
2279 get_task_struct(pos); 2280 get_task_struct(pos);
2280 else 2281 else
2281 pos = NULL; 2282 pos = NULL;
2282 read_unlock(&tasklist_lock); 2283 rcu_read_unlock();
2283 put_task_struct(start); 2284 put_task_struct(start);
2284 return pos; 2285 return pos;
2285} 2286}