diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2018-08-15 20:22:14 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2018-08-15 20:22:14 +0000 |
commit | 23dc805f86c12b02357c1d875d069a5cb0b2ab05 (patch) | |
tree | 04454b65f85f360f81f6a585a33397596eb6e23b | |
parent | d9871b145155a6c13358f6679537449ae6db7da2 (diff) |
Push back the kernel lock in sys_mmap(2) a little bit more now that
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@
-rw-r--r-- | sys/uvm/uvm_mmap.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 11effbc411a..e4bf3647f2c 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -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); } |