pid: Implement ns_of_pid
Subsystems (3)
A message that is not in the archive (sent off-list or not yet received): [email protected]
Resending with complete cc list.
Sukadev Bhattiprolu [[email protected]] wrote:
| This and following patch were discussed a couple of times but I | did not see any objections to them. The ns_of_pid() introduced | here will also be used in a follow-on patch to fix si_pid from | mqueue. | | --- | From: Sukadev Bhattiprolu <[email protected]> | Date: Fri, 12 Dec 2008 11:44:55 -0800 | Subject: [PATCH 1/2] pid: Implement ns_of_pid | | A current problem with the pid namespace is that it is | easy to do pid related work after exit_task_namespaces which | drops the nsproxy pointer. | | However if we are doing pid namespace related work we are | always operating on some struct pid which retains the pid_namespace | pointer of the pid namespace it was allocated in. | | So provide ns_of_pid which allows us to find the pid | namespace a pid was allocated in. | | Using this we have the needed infrastructure to do pid | namespace related work at anytime we have a struct pid, | removing the chance of accidentally having a NULL | pointer dereference when accessing current->nsproxy. | | Signed-off-by: Eric W. Biederman <[email protected]> | --- | include/linux/pid.h | 11 +++++++++++ | 1 files changed, 11 insertions(+), 0 deletions(-) | | diff --git a/include/linux/pid.h b/include/linux/pid.h | index d7e98ff..e9aec85 100644 | --- a/include/linux/pid.h | +++ b/include/linux/pid.h | @@ -122,6 +122,17 @@ int next_pidmap(struct pid_namespace *pid_ns, int last); | extern struct pid *alloc_pid(struct pid_namespace *ns); | extern void free_pid(struct pid *pid); | | +/* ns_of_pid returns the pid namespace in which the specified | + * pid was allocated. | + */ | +static inline struct pid_namespace *ns_of_pid(struct pid *pid) | +{ | + struct pid_namespace *ns = NULL; | + if (pid) | + ns = pid->numbers[pid->level].ns; | + return ns; | +} | + | /* | * the helpers to get the pid's id seen from different namespaces | * | -- | 1.5.2.5 |
PATCH 2/2 pid: Generalize task_active_pid_ns
In reply to a message not in the archiveFrom: Sukadev Bhattiprolu <[email protected]>
Date: Fri, 12 Dec 2008 11:49:27 -0800
Subject: [PATCH 2/2] pid: Generalize task_active_pid_ns
Currently task_active_pid_ns is not safe to call after a task becomes a zombie and exit_task_namespaces is called, as nsproxy becomes NULL. By reading the pid namespace from the pid of the task we can trivially solve this problem at the cost of one extra memory read in what should be the same cacheline as we read the namespace from.
When moving things around I have made task_active_pid_ns out of line because keeping it in pid_namespace.h would require adding includes of pid.h and sched.h that I don't think we want.
This change does make task_active_pid_ns unsafe to call during copy_process until we attach a pid on the task_struct which seems to be a reasonable trade off.
--- include/linux/pid_namespace.h | 6 +----- kernel/fork.c | 4 ++-- kernel/pid.c | 6 ++++++ 3 files changed, 9 insertions(+), 7 deletions(-)
include/linux/pid_namespace.h +1 -5
@@ -79,11 +79,7 @@ static inline void zap_pid_ns_processes(struct pid_namespace *ns) }#endif /* CONFIG_PID_NS */ -static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) -{ -return tsk->nsproxy->pid_ns; -} - +extern struct pid_namespace *task_active_pid_ns (struct task_struct *tsk);void pidhash_init (void );void pidmap_init (void );
kernel/fork.c +2 -2
@@ -1100,12 +1100,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,if (pid != &init_struct_pid) { retval = -ENOMEM ; - pid =alloc_pid (task_active_pid_ns (p)); + pid =alloc_pid (p->nsproxy->pid_ns);if (!pid) goto bad_fork_cleanup_io;if (clone_flags &CLONE_NEWPID ) { - retval =pid_ns_prepare_proc (task_active_pid_ns (p)); + retval =pid_ns_prepare_proc (p->nsproxy->pid_ns);if (retval <0 ) goto bad_fork_free_pid; }
kernel/pid.c +6 -0
@@ -474,6 +474,12 @@ pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) }EXPORT_SYMBOL (task_session_nr_ns); +struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) +{ +return ns_of_pid (task_pid (tsk)); +} +EXPORT_SYMBOL_GPL (task_active_pid_ns); +/* * Used by proc to find the first pid that is greater then or equal to nr. *
Signature · 1 line
1.5.2.5
Re: [PATCH 2/2] pid: Generalize task_active_pid_ns
Quoted 11 lines · Sukadev Bhattiprolu
From: Sukadev Bhattiprolu <[email protected]>
Date: Fri, 12 Dec 2008 11:49:27 -0800
Subject: [PATCH 2/2] pid: Generalizetask_active_pid_nsCurrently
task_active_pid_nsis not safe to call after a task becomes a zombie andexit_task_namespacesis called, as nsproxy becomes NULL. By reading the pid namespace from the pid of the task we can trivially solve this problem at the cost of one extra memory read in what should be the same cacheline as we read the namespace from.
Quoted 8 lines
When moving things around I have made
task_active_pid_nsout of line because keeping it inpid_namespace.hwould require adding includes ofpid.handsched.hthat I don't think we want.This change does make
task_active_pid_nsunsafe to call duringcopy_processuntil we attach a pid on thetask_structwhich seems to be a reasonable trade off.
Yeah that's not really much of a tradeoff... the text for those lines gets shorter! :)
(to all three)
thanks,
-serge
Quoted 67 lines
Signed-off-by Eric W. Biederman <[email protected]>--- include/linux/pid_namespace.h | 6 +----- kernel/fork.c | 4 ++-- kernel/pid.c | 6 ++++++ 3 files changed, 9 insertions(+), 7 deletions(-)include/linux/pid_namespace.h +1
-5@@ -79,11 +79,7 @@ static inline void zap_pid_ns_processes(struct pid_namespace *ns) }#endif /* CONFIG_PID_NS */ -static inline struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) -{ -return tsk->nsproxy->pid_ns; -} - +extern struct pid_namespace *task_active_pid_ns (struct task_struct *tsk);void pidhash_init (void );void pidmap_init (void );kernel/fork.c +2
-2@@ -1100,12 +1100,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,if (pid != &init_struct_pid) { retval = -ENOMEM ; - pid =alloc_pid (task_active_pid_ns (p)); + pid =alloc_pid (p->nsproxy->pid_ns);if (!pid) goto bad_fork_cleanup_io;if (clone_flags &CLONE_NEWPID ) { - retval =pid_ns_prepare_proc (task_active_pid_ns (p)); + retval =pid_ns_prepare_proc (p->nsproxy->pid_ns);if (retval <0 ) goto bad_fork_free_pid; }kernel/pid.c +6
-0@@ -474,6 +474,12 @@ pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) }EXPORT_SYMBOL (task_session_nr_ns); +struct pid_namespace *task_active_pid_ns (struct task_struct *tsk) +{ +return ns_of_pid (task_pid (tsk)); +} +EXPORT_SYMBOL_GPL (task_active_pid_ns); +/* * Used by proc to find the first pid that is greater then or equal to nr. * Signature · 6 lines
1.5.2.5 _______________________________________________ Containers mailing list [email protected] https://lists.linux-foundation.org/mailman/listinfo/containers