The new and relatively unused (compared to VM ops) mm_struct exe file reference
uses the mmap semaphore. It may be preferrable to avoid using the mmap
semaphore at some point in the future. This patch demonstrates one way to avoid
using the mmap semaphore for the exe file reference inside /proc/pid/exe ops.
Unfortunately we can't entirely avoid using the mmap semaphore because we need
to drop the exe file reference when the VMA mapping the executable file does --
otherwise we'd pin mounted filesystems until all applications executed from
them exitted.
Signed-off-by: Matt Helsley <[email protected]>
---
include/linux/sched.h | 1 +
mm/mmap.c | 17 +++++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
Index: linux-2.6.23/include/linux/sched.h
===================================================================
--- linux-2.6.23.orig/include/linux/sched.h
+++ linux-2.6.23/include/linux/sched.h
@@ -432,10 +432,11 @@ struct mm_struct {
/* aio bits */
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list;
/* store ref to file /proc/<pid>/exe symlink points to */
+ spinlock_t exe_file_lock;
struct file *exe_file;
};
struct sighand_struct {
atomic_t count;
Index: linux-2.6.23/mm/mmap.c
===================================================================
--- linux-2.6.23.orig/mm/mmap.c
+++ linux-2.6.23/mm/mmap.c
@@ -1706,27 +1706,27 @@ find_extend_vma(struct mm_struct * mm, u
* reference; only puts old ones */
void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
{
struct file *old_exe_file;
- down_write(&mm->mmap_sem);
+ spin_lock(&mm->exe_file_lock);
old_exe_file = mm->exe_file;
mm->exe_file = new_exe_file;
- up_write(&mm->mmap_sem);
+ spin_unlock(&mm->exe_file_lock);
if (old_exe_file)
fput(old_exe_file);
}
struct file *get_mm_exe_file(struct mm_struct *mm)
{
struct file *exe_file;
- down_read(&mm->mmap_sem);
+ spin_lock(&mm->exe_file_lock);
exe_file = mm->exe_file;
if (exe_file)
get_file(exe_file);
- up_read(&mm->mmap_sem);
+ spin_unlock(&mm->exe_file_lock);
return exe_file;
}
#endif
/*
@@ -1744,14 +1744,19 @@ static void remove_vma_list(struct mm_st
mm->total_vm -= nrpages;
if (vma->vm_flags & VM_LOCKED)
mm->locked_vm -= nrpages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
+ spin_lock(&mm->exe_file_lock);
if (mm->exe_file && (vma->vm_file == mm->exe_file)) {
- fput(mm->exe_file);
+ struct file *old_exe_file = mm->exe_file;
+
mm->exe_file = NULL;
- }
+ spin_unlock(&mm->exe_file_lock);
+ fput(old_exe_file);
+ } else
+ spin_unlock(&mm->exe_file_lock);
vma = remove_vma(vma);
} while (vma);
validate_mm(mm);
}
--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]