提交 5e85d4ab 编写于 作者: E Eric W. Biederman 提交者: Linus Torvalds

[PATCH] task: Make task list manipulations RCU safe

While we can currently walk through thread groups, process groups, and
sessions with just the rcu_read_lock, this opens the door to walking the
entire task list.

We already have all of the other RCU guarantees so there is no cost in
doing this, this should be enough so that proc can stop taking the
tasklist lock during readdir.

prev_task was killed because it has no users, and using it will miss new
tasks when doing an rcu traversal.
Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 181ae400
...@@ -712,7 +712,7 @@ static int de_thread(struct task_struct *tsk) ...@@ -712,7 +712,7 @@ static int de_thread(struct task_struct *tsk)
attach_pid(current, PIDTYPE_PID, current->pid); attach_pid(current, PIDTYPE_PID, current->pid);
attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); attach_pid(current, PIDTYPE_PGID, current->signal->pgrp);
attach_pid(current, PIDTYPE_SID, current->signal->session); attach_pid(current, PIDTYPE_SID, current->signal->session);
list_add_tail(&current->tasks, &init_task.tasks); list_add_tail_rcu(&current->tasks, &init_task.tasks);
current->group_leader = current; current->group_leader = current;
leader->group_leader = current; leader->group_leader = current;
......
...@@ -1192,8 +1192,7 @@ extern void wait_task_inactive(task_t * p); ...@@ -1192,8 +1192,7 @@ extern void wait_task_inactive(task_t * p);
#define remove_parent(p) list_del_init(&(p)->sibling) #define remove_parent(p) list_del_init(&(p)->sibling)
#define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) #define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children)
#define next_task(p) list_entry((p)->tasks.next, struct task_struct, tasks) #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks)
#define prev_task(p) list_entry((p)->tasks.prev, struct task_struct, tasks)
#define for_each_process(p) \ #define for_each_process(p) \
for (p = &init_task ; (p = next_task(p)) != &init_task ; ) for (p = &init_task ; (p = next_task(p)) != &init_task ; )
......
...@@ -56,7 +56,7 @@ static void __unhash_process(struct task_struct *p) ...@@ -56,7 +56,7 @@ static void __unhash_process(struct task_struct *p)
detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_PGID);
detach_pid(p, PIDTYPE_SID); detach_pid(p, PIDTYPE_SID);
list_del_init(&p->tasks); list_del_rcu(&p->tasks);
__get_cpu_var(process_counts)--; __get_cpu_var(process_counts)--;
} }
list_del_rcu(&p->thread_group); list_del_rcu(&p->thread_group);
......
...@@ -1204,7 +1204,7 @@ static task_t *copy_process(unsigned long clone_flags, ...@@ -1204,7 +1204,7 @@ static task_t *copy_process(unsigned long clone_flags,
attach_pid(p, PIDTYPE_PGID, process_group(p)); attach_pid(p, PIDTYPE_PGID, process_group(p));
attach_pid(p, PIDTYPE_SID, p->signal->session); attach_pid(p, PIDTYPE_SID, p->signal->session);
list_add_tail(&p->tasks, &init_task.tasks); list_add_tail_rcu(&p->tasks, &init_task.tasks);
__get_cpu_var(process_counts)++; __get_cpu_var(process_counts)++;
} }
attach_pid(p, PIDTYPE_PID, p->pid); attach_pid(p, PIDTYPE_PID, p->pid);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册