login
Header Space

 
 

Re: rfc, leader_pid_type()

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Eric W. Biederman <ebiederm@...>
Cc: Pavel Emelyanov <xemul@...>, <linux-kernel@...>
Date: Wednesday, March 19, 2008 - 10:36 am

On 03/19, Oleg Nesterov wrote:

To clarify: we can't change detach_pid() and remove the line that clears
task->pids[type].pid right now. Look for example at get_task_pid(), it
could be used without rcu, using the previously pinned task_struct.

But in the long term this might be right.

(As for pid_alive(). Can't we rename it? Its name is very misleading, and it
 shouldn't play with ->pids, this looks confusing. Just do p->sighand != 0)


Something like the patch below. What do you think? setsid/setpgrp now
can use change_pid(). The change in transfer_pid() needs a separate
patch with the fat changelog.

This doesn't solve the problem with task_tgid() == NULL, but at least
this is not possible with task == current.

Oleg.

--- 25/kernel/pid.c~1_PID_CHANGE	2008-02-16 17:51:17.000000000 +0300
+++ 25/kernel/pid.c	2008-03-19 17:15:15.000000000 +0300
@@ -317,29 +317,25 @@ EXPORT_SYMBOL_GPL(find_pid);
 /*
  * attach_pid() must be called with the tasklist_lock write-held.
  */
-int attach_pid(struct task_struct *task, enum pid_type type,
-		struct pid *pid)
+int attach_pid(struct task_struct *task, enum pid_type type, struct pid *pid)
 {
-	struct pid_link *link;
+	struct pid_link *link = &task->pids[type];
 
-	link = &task->pids[type];
 	link->pid = pid;
-	hlist_add_head_rcu(&link->node, &pid->tasks[type]);
+	if (likely(pid != NULL))
+		hlist_add_head_rcu(&link->node, &pid->tasks[type]);
 
 	return 0;
 }
 
-void detach_pid(struct task_struct *task, enum pid_type type)
+void change_pid(struct task_struct *task, enum pid_type type, struct pid *new)
 {
-	struct pid_link *link;
-	struct pid *pid;
+	struct pid_link *link = &task->pids[type];
+	struct pid *pid = link->pid;
 	int tmp;
 
-	link = &task->pids[type];
-	pid = link->pid;
-
 	hlist_del_rcu(&link->node);
-	link->pid = NULL;
+	attach_pid(task, type, new);
 
 	for (tmp = PIDTYPE_MAX; --tmp >= 0; )
 		if (!hlist_empty(&pid->tasks[tmp]))
@@ -348,13 +344,17 @@ void detach_pid(struct task_struct *task
 	free_pid(pid);
 }
 
+void detach_pid(struct task_struct *task, enum pid_type type)
+{
+	change_pid(task, type, NULL);
+}
+
 /* transfer_pid is an optimization of attach_pid(new), detach_pid(old) */
 void transfer_pid(struct task_struct *old, struct task_struct *new,
 			   enum pid_type type)
 {
 	new->pids[type].pid = old->pids[type].pid;
 	hlist_replace_rcu(&old->pids[type].node, &new->pids[type].node);
-	old->pids[type].pid = NULL;
 }
 
 struct task_struct *pid_task(struct pid *pid, enum pid_type type)

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: rfc, leader_pid_type(), Oleg Nesterov, (Tue Mar 18, 8:31 pm)
Re: rfc, leader_pid_type(), Oleg Nesterov, (Wed Mar 19, 10:36 am)
speck-geostationary