summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2003-05-25 01:10:37 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2003-05-25 01:10:37 -0700
commit055e188d5ce5d5edd5d916a0cd549ebb195388a3 (patch)
treeb1f2d4dd72df0d360f528aa8107a62fe47fe5e6d /include/linux
parent05cdeac3efd3bbffd5f01a1822c4f941e19ba31d (diff)
[PATCH] Fix dcache_lock/tasklist_lock ranking bug
__unhash_process acquires the dcache_lock while holding the tasklist_lock for writing. This can deadlock. Additionally, fs/proc/base.c incorrectly assumed that p->pid would be set to 0 during release_task. The patch fixes that by adding a new spinlock to the task structure and fixing all references to (!p->pid). The alternative to the new spinlock would be to hold dcache_lock around __unhash_process. - fs/proc/base.c assumed that p->pid is reset to 0 during exit. This is not the case anymore. I now look at the count of the pid structure for PIDTYPE_PID. - de_thread now tested - as broken as it was before: open handles to /proc/<pid> are either stale or invalid after an exec of a nptl process, if the exec was call from a secondary thread. - a few lock_kernels removed - that part of /proc doesn't need it. - additional instances of 'if(current->pid)' replaced with pid_alive.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/proc_fs.h2
-rw-r--r--include/linux/sched.h2
3 files changed, 5 insertions, 0 deletions
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 96a5f926300e..6372a411be8f 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -101,6 +101,7 @@
.blocked = {{0}}, \
.posix_timers = LIST_HEAD_INIT(tsk.posix_timers), \
.alloc_lock = SPIN_LOCK_UNLOCKED, \
+ .proc_lock = SPIN_LOCK_UNLOCKED, \
.switch_lock = SPIN_LOCK_UNLOCKED, \
.journal_info = NULL, \
}
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 0dd15d1cb2e2..4607df82fd93 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -87,6 +87,8 @@ extern void proc_root_init(void);
extern void proc_misc_init(void);
struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry);
+struct dentry *proc_pid_unhash(struct task_struct *p);
+void proc_pid_flush(struct dentry *proc_dentry);
int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir);
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 46981bca766f..75e6e1b5b363 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -429,6 +429,8 @@ struct task_struct {
u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty */
spinlock_t alloc_lock;
+/* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
+ spinlock_t proc_lock;
/* context-switch lock */
spinlock_t switch_lock;