]> git.hungrycats.org Git - linux/commitdiff
[PATCH] user-vm-unlock-2.5.31-A2
authorIngo Molnar <mingo@elte.hu>
Tue, 13 Aug 2002 07:36:37 +0000 (00:36 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 13 Aug 2002 07:36:37 +0000 (00:36 -0700)
This implements CLONE_VM_RELEASE, which lets the child release the 'user
VM' at mm_release() time.

arch/i386/kernel/process.c
include/linux/sched.h
kernel/fork.c

index fdcd260eba588fe8c434b5a58a0771718db5f412..49cb22992039693d133c2c184c6406fcb4091dfc 100644 (file)
@@ -566,6 +566,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        struct_cpy(childregs, regs);
        childregs->eax = 0;
        childregs->esp = esp;
+       p->user_vm_lock = NULL;
 
        p->thread.esp = (unsigned long) childregs;
        p->thread.esp0 = (unsigned long) (childregs+1);
@@ -579,6 +580,19 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
        unlazy_fpu(tsk);
        struct_cpy(&p->thread.i387, &tsk->thread.i387);
 
+       if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
+               p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+               if (!p->thread.ts_io_bitmap)
+                       return -ENOMEM;
+               memcpy(p->thread.ts_io_bitmap, tsk->thread.ts_io_bitmap,
+                       IO_BITMAP_BYTES);
+       }
+
+       /*
+        * The common fastpath:
+        */
+       if (!(clone_flags & (CLONE_SETTLS | CLONE_SETTID | CLONE_RELEASE_VM)))
+               return 0;
        /*
         * Set a new TLS for the child thread?
         */
@@ -608,14 +622,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
                if (put_user(p->pid, (pid_t *)childregs->edx))
                        return -EFAULT;
 
-       if (unlikely(NULL != tsk->thread.ts_io_bitmap)) {
-               p->thread.ts_io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
-               if (!p->thread.ts_io_bitmap)
-                       return -ENOMEM;
-               memcpy(p->thread.ts_io_bitmap, tsk->thread.ts_io_bitmap,
-                       IO_BITMAP_BYTES);
+       /*
+        * Does the userspace VM want any unlock on mm_release()?
+        */
+       if (clone_flags & CLONE_RELEASE_VM) {
+               childregs->esp -= sizeof(0UL);
+               p->user_vm_lock = (long *) esp;
        }
-
        return 0;
 }
 
index 63a6b938b1457b6e4863dba1d3c085c1be475835..fcd107c3d29ccee81517c74dfc2b59de32acf5f1 100644 (file)
@@ -48,6 +48,7 @@ struct exec_domain;
 #define CLONE_SETTLS   0x00080000      /* create a new TLS for the child */
 #define CLONE_SETTID   0x00100000      /* write the TID back to userspace */
 #define CLONE_DETACHED 0x00200000      /* parent wants no child-exit signal */
+#define CLONE_RELEASE_VM 0x00400000    /* release the userspace VM */
 
 #define CLONE_SIGNAL   (CLONE_SIGHAND | CLONE_THREAD)
 
@@ -306,6 +307,7 @@ struct task_struct {
 
        wait_queue_head_t wait_chldexit;        /* for wait4() */
        struct completion *vfork_done;          /* for vfork() */
+       long *user_vm_lock;                     /* for CLONE_RELEASE_VM */
 
        unsigned long rt_priority;
        unsigned long it_real_value, it_prof_value, it_virt_value;
index 95baf7236910662ce3c13ee7d2ce5f8abfc2d731..3cb62cfcf4fd541e8c783da959bd8ddf1803856e 100644 (file)
@@ -367,6 +367,12 @@ void mm_release(void)
                tsk->vfork_done = NULL;
                complete(vfork_done);
        }
+       if (tsk->user_vm_lock)
+               /*
+                * We dont check the error code - if userspace has
+                * not set up a proper pointer then tough luck.
+                */
+               put_user(0UL, tsk->user_vm_lock);
 }
 
 static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)