Push back the kernel lock in sys_mmap(2) a little bit more now that
authorkettenis <kettenis@openbsd.org>
Wed, 15 Aug 2018 20:22:13 +0000 (20:22 +0000)
committerkettenis <kettenis@openbsd.org>
Wed, 15 Aug 2018 20:22:13 +0000 (20:22 +0000)
fd_getfile(9) is mpsafe.  Note that sys_mmap(2) isn't actually unlocked
currently.  However this diff has been tested with it unlocked, and I
hope to unlock it for real soon-ish.

ok visa@, mpi@

sys/uvm/uvm_mmap.c

index 11effbc..e4bf364 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uvm_mmap.c,v 1.150 2018/04/27 10:13:37 mpi Exp $      */
+/*     $OpenBSD: uvm_mmap.c,v 1.151 2018/08/15 20:22:13 kettenis Exp $ */
 /*     $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $        */
 
 /*
@@ -428,11 +428,8 @@ sys_mmap(struct proc *p, void *v, register_t *retval)
 
        /* check for file mappings (i.e. not anonymous) and verify file. */
        if ((flags & MAP_ANON) == 0) {
-               KERNEL_LOCK();
-               if ((fp = fd_getfile(fdp, fd)) == NULL) {
-                       KERNEL_UNLOCK();
+               if ((fp = fd_getfile(fdp, fd)) == NULL)
                        return (EBADF);
-               }
 
                if (fp->f_type != DTYPE_VNODE) {
                        error = ENODEV;         /* only mmap vnodes! */
@@ -456,8 +453,6 @@ sys_mmap(struct proc *p, void *v, register_t *retval)
                        flags |= MAP_ANON;
                        FRELE(fp, p);
                        fp = NULL;
-                       /* XXX */
-                       KERNEL_UNLOCK();
                        goto is_anon;
                }
 
@@ -507,8 +502,10 @@ sys_mmap(struct proc *p, void *v, register_t *retval)
                         * EPERM.
                         */
                        if (fp->f_flag & FWRITE) {
-                               if ((error =
-                                   VOP_GETATTR(vp, &va, p->p_ucred, p)))
+                               KERNEL_LOCK();
+                               error = VOP_GETATTR(vp, &va, p->p_ucred, p);
+                               KERNEL_UNLOCK();
+                               if (error)
                                        goto out;
                                if ((va.va_flags & (IMMUTABLE|APPEND)) == 0)
                                        maxprot |= PROT_WRITE;
@@ -533,8 +530,10 @@ sys_mmap(struct proc *p, void *v, register_t *retval)
                                goto out;
                        }
                }
+               KERNEL_LOCK();
                error = uvm_mmapfile(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
                    flags, vp, pos, p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur, p);
+               KERNEL_UNLOCK();
        } else {                /* MAP_ANON case */
                if (fd != -1)
                        return EINVAL;
@@ -568,10 +567,8 @@ is_anon:   /* label for SunOS style /dev/zero */
                *retval = (register_t)(addr + pageoff);
 
 out:
-       if (fp) {
+       if (fp)
                FRELE(fp, p);
-               KERNEL_UNLOCK();
-       }
        return (error);
 }