From: Eric W. Biederman I just refactored fs/proc/base.c to use task_refs to ensure there are not long user triggerable hold times of task_struct. It looks like I missed cpuset.c. Oops. This patch updates proc_cpuset_show to handle the task dying between when the file is opened and when data is read out. Signed-off-by: Eric W. Biederman Cc: Paul Jackson Signed-off-by: Andrew Morton --- kernel/cpuset.c | 32 +++++++++++++++++++++----------- 1 files changed, 21 insertions(+), 11 deletions(-) diff -puN kernel/cpuset.c~proc-dont-lock-task_structs-indefinitely-cpuset-fix-2 kernel/cpuset.c --- devel/kernel/cpuset.c~proc-dont-lock-task_structs-indefinitely-cpuset-fix-2 2006-02-28 17:18:27.000000000 -0800 +++ devel-akpm/kernel/cpuset.c 2006-02-28 17:18:27.000000000 -0800 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -2379,37 +2380,46 @@ void __cpuset_memory_pressure_bump(void) static int proc_cpuset_show(struct seq_file *m, void *v) { struct cpuset *cs; + struct task_ref *tref; struct task_struct *tsk; char *buf; - int retval = 0; + int retval; + retval = -ENOMEM; buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) - return -ENOMEM; + goto out; + + retval = -ESRCH; + tref = m->private; + tsk = get_tref_task(tref); + if (!tsk) + goto out_free; - tsk = m->private; + retval = -EINVAL; mutex_lock(&manage_mutex); cs = tsk->cpuset; - if (!cs) { - retval = -EINVAL; - goto out; - } + if (!cs) + goto out_unlock; retval = cpuset_path(cs, buf, PAGE_SIZE); if (retval < 0) - goto out; + goto out_unlock; seq_puts(m, buf); seq_putc(m, '\n'); -out: +out_unlock: mutex_unlock(&manage_mutex); + put_task_struct(tsk); +out_free: kfree(buf); +out: return retval; } static int cpuset_open(struct inode *inode, struct file *file) { - struct task_struct *tsk = PROC_I(inode)->task; - return single_open(file, proc_cpuset_show, tsk); + struct task_ref *tref = PROC_I(inode)->tref; + return single_open(file, proc_cpuset_show, tref); } struct file_operations proc_cpuset_operations = { _