Date: Thu, 10 Sep 2020 20:54:45 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r365613 - head/sys/kern Message-ID: <202009102054.08AKsjYQ056440@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Sep 10 20:54:44 2020 New Revision: 365613 URL: https://svnweb.freebsd.org/changeset/base/365613 Log: Fix interaction between largepages and seals/writes. On write with SHM_GROW_ON_WRITE, use proper truncate. Do not allow to grow largepage shm if F_SEAL_GROW is set. Note that shrinks are not supported at all due to unmanaged mappings. Call to vm_pager_update_writecount() is only valid for swap objects, skip it for unmanaged largepages. Largepages cannot support write sealing. Do not writecnt largepage mappings. Reported by: kevans Reviewed by: kevans, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D26394 Modified: head/sys/kern/uipc_shm.c Modified: head/sys/kern/uipc_shm.c ============================================================================== --- head/sys/kern/uipc_shm.c Thu Sep 10 20:46:16 2020 (r365612) +++ head/sys/kern/uipc_shm.c Thu Sep 10 20:54:44 2020 (r365613) @@ -450,9 +450,7 @@ shm_write(struct file *fp, struct uio *uio, struct ucr error = 0; if ((shmfd->shm_flags & SHM_GROW_ON_WRITE) != 0 && size > shmfd->shm_size) { - VM_OBJECT_WLOCK(shmfd->shm_object); - error = shm_dotruncate_locked(shmfd, size, rl_cookie); - VM_OBJECT_WUNLOCK(shmfd->shm_object); + error = shm_dotruncate_cookie(shmfd, size, rl_cookie); } if (error == 0) error = uiomove_object(shmfd->shm_object, @@ -767,6 +765,9 @@ shm_dotruncate_largepage(struct shmfd *shmfd, off_t le #endif } + if ((shmfd->shm_seals & F_SEAL_GROW) != 0) + return (EPERM); + aflags = VM_ALLOC_NORMAL | VM_ALLOC_ZERO; if (shmfd->shm_lp_alloc_policy == SHM_LARGEPAGE_ALLOC_NOWAIT) aflags |= VM_ALLOC_WAITFAIL; @@ -1416,7 +1417,7 @@ out: static int shm_mmap_large(struct shmfd *shmfd, vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, vm_prot_t max_prot, int flags, - vm_ooffset_t foff, bool writecounted, struct thread *td) + vm_ooffset_t foff, struct thread *td) { struct vmspace *vms; vm_map_entry_t next_entry, prev_entry; @@ -1448,8 +1449,6 @@ shm_mmap_large(struct shmfd *shmfd, vm_map_t map, vm_o docow |= MAP_INHERIT_SHARE; if ((flags & MAP_NOCORE) != 0) docow |= MAP_DISABLE_COREDUMP; - if (writecounted) - docow |= MAP_WRITECOUNT; mask = pagesizes[shmfd->shm_lp_psind] - 1; if ((foff & mask) != 0) @@ -1594,12 +1593,15 @@ shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *a mtx_unlock(&shm_timestamp_lock); vm_object_reference(shmfd->shm_object); - if (writecnt) - vm_pager_update_writecount(shmfd->shm_object, 0, objsize); if (shm_largepage(shmfd)) { + writecnt = false; error = shm_mmap_large(shmfd, map, addr, objsize, prot, - maxprot, flags, foff, writecnt, td); + maxprot, flags, foff, td); } else { + if (writecnt) { + vm_pager_update_writecount(shmfd->shm_object, 0, + objsize); + } error = vm_mmap_object(map, addr, objsize, prot, maxprot, flags, shmfd->shm_object, foff, writecnt, td); } @@ -1838,6 +1840,11 @@ shm_add_seals(struct file *fp, int seals) } nseals = seals & ~shmfd->shm_seals; if ((nseals & F_SEAL_WRITE) != 0) { + if (shm_largepage(shmfd)) { + error = ENOTSUP; + goto out; + } + /* * The rangelock above prevents writable mappings from being * added after we've started applying seals. The RLOCK here
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009102054.08AKsjYQ056440>