diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-06-26 03:26:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 12:58:26 -0400 |
commit | cc288738c9ae3c64d3c50b86604044d1f6d22941 (patch) | |
tree | 87058616bfa84572647fbe574fe733e81c1d17b6 /fs/proc/base.c | |
parent | df26c40e567356caeefe2861311e19c54444d917 (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.c | 11 |
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 | */ |
2227 | static struct task_struct *first_tid(struct task_struct *leader, int tid, int nr) | 2227 | static 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; |
2260 | done: | 2261 | done: |
2261 | read_unlock(&tasklist_lock); | 2262 | rcu_read_unlock(); |
2262 | return pos; | 2263 | return pos; |
2263 | } | 2264 | } |
2264 | 2265 | ||
@@ -2271,7 +2272,7 @@ done: | |||
2271 | static struct task_struct *next_tid(struct task_struct *start) | 2272 | static 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 | } |