Date: Thu, 20 Jun 2013 21:50:04 +0000 (UTC) From: Attilio Rao <attilio@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r252046 - in user/attilio/vmobj-readlock/sys: cddl/contrib/opensolaris/uts/common/fs/zfs dev/drm2/i915 dev/drm2/ttm fs/tmpfs kern vm Message-ID: <201306202150.r5KLo401090325@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: attilio Date: Thu Jun 20 21:50:04 2013 New Revision: 252046 URL: http://svnweb.freebsd.org/changeset/base/252046 Log: When switching to atomics for handling the busy bit this means we cannot rely any-longer on the object lock to protect between the lookup/allocation, the sleep and the actual page busing. Busy the page also in read mode, directly in vm_page_alloc()/vm_page_grab() after the lookup/allocation is just performed. This will leave the behaviour consistent. Sponsored by: EMC / Isilon storage division Modified: user/attilio/vmobj-readlock/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c user/attilio/vmobj-readlock/sys/dev/drm2/ttm/ttm_tt.c user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c user/attilio/vmobj-readlock/sys/kern/kern_exec.c user/attilio/vmobj-readlock/sys/vm/vm_page.c user/attilio/vmobj-readlock/sys/vm/vm_page.h Modified: user/attilio/vmobj-readlock/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ============================================================================== --- user/attilio/vmobj-readlock/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Jun 20 21:50:04 2013 (r252046) @@ -349,17 +349,17 @@ page_busy(vnode_t *vp, int64_t start, in zfs_vmobject_wlock(obj); continue; } + vm_page_io_start(pp); } else pp = NULL; if (pp == NULL && alloc) pp = vm_page_alloc(obj, OFF_TO_IDX(start), VM_ALLOC_SYSTEM | VM_ALLOC_IFCACHED | - VM_ALLOC_NOBUSY); + VM_ALLOC_RBUSY); if (pp != NULL) { ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL); - vm_page_io_start(pp); if (alloc) { vm_object_pip_add(obj, 1); pmap_remove_write(pp); @@ -494,10 +494,9 @@ mappedread_sf(vnode_t *vp, int nbytes, u for (start = uio->uio_loffset; len > 0; start += PAGESIZE) { int bytes = MIN(PAGESIZE, len); - pp = vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_NOBUSY | + pp = vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_RBUSY | VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_IGN_RBUSY); if (pp->valid == 0) { - vm_page_io_start(pp); zfs_vmobject_wunlock(obj); va = zfs_map_page(pp, &sf); error = dmu_read(os, zp->z_id, start, bytes, va, @@ -515,7 +514,8 @@ mappedread_sf(vnode_t *vp, int nbytes, u vm_page_activate(pp); } vm_page_unlock(pp); - } + } else + vm_page_io_finish(pp); if (error) break; uio->uio_resid -= bytes; Modified: user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c ============================================================================== --- user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c Thu Jun 20 21:50:04 2013 (r252046) @@ -2507,10 +2507,8 @@ i915_gem_wire_page(vm_object_t object, v int rv; VM_OBJECT_ASSERT_WLOCKED(object); - m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | - VM_ALLOC_RETRY); + m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { - vm_page_busy(m); if (vm_pager_has_page(object, pindex, NULL, NULL)) { rv = vm_pager_get_pages(object, &m, 1, 0); m = vm_page_lookup(object, pindex); @@ -2527,7 +2525,6 @@ i915_gem_wire_page(vm_object_t object, v m->valid = VM_PAGE_BITS_ALL; m->dirty = 0; } - vm_page_wakeup(m); } vm_page_lock(m); vm_page_wire(m); Modified: user/attilio/vmobj-readlock/sys/dev/drm2/ttm/ttm_tt.c ============================================================================== --- user/attilio/vmobj-readlock/sys/dev/drm2/ttm/ttm_tt.c Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/dev/drm2/ttm/ttm_tt.c Thu Jun 20 21:50:04 2013 (r252046) @@ -288,10 +288,8 @@ int ttm_tt_swapin(struct ttm_tt *ttm) VM_OBJECT_WLOCK(obj); vm_object_pip_add(obj, 1); for (i = 0; i < ttm->num_pages; ++i) { - from_page = vm_page_grab(obj, i, VM_ALLOC_NOBUSY | - VM_ALLOC_RETRY); + from_page = vm_page_grab(obj, i, VM_ALLOC_RETRY); if (from_page->valid != VM_PAGE_BITS_ALL) { - vm_page_busy(from_page); if (vm_pager_has_page(obj, i, NULL, NULL)) { rv = vm_pager_get_pages(obj, &from_page, 1, 0); if (rv != VM_PAGER_OK) { @@ -303,8 +301,8 @@ int ttm_tt_swapin(struct ttm_tt *ttm) } } else vm_page_zero_invalid(from_page, TRUE); - vm_page_wakeup(from_page); } + vm_page_wakeup(from_page); to_page = ttm->pages[i]; if (unlikely(to_page == NULL)) { ret = -ENOMEM; Modified: user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c ============================================================================== --- user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c Thu Jun 20 21:50:04 2013 (r252046) @@ -454,10 +454,8 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p * lock to page out tobj's pages because tobj is a OBJT_SWAP * type object. */ - m = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY | - VM_ALLOC_NOBUSY); + m = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { - vm_page_busy(m); if (vm_pager_has_page(tobj, idx, NULL, NULL)) { rv = vm_pager_get_pages(tobj, &m, 1, 0); m = vm_page_lookup(tobj, idx); @@ -480,8 +478,8 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p } } else vm_page_zero_invalid(m, TRUE); - vm_page_wakeup(m); } + vm_page_wakeup(m); vm_page_io_start(m); VM_OBJECT_WUNLOCK(tobj); error = uiomove_fromphys(&m, offset, tlen, uio); @@ -571,10 +569,8 @@ tmpfs_mappedwrite(vm_object_t tobj, size tlen = MIN(PAGE_SIZE - offset, len); VM_OBJECT_WLOCK(tobj); - tpg = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | - VM_ALLOC_RETRY); + tpg = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (tpg->valid != VM_PAGE_BITS_ALL) { - vm_page_busy(tpg); if (vm_pager_has_page(tobj, idx, NULL, NULL)) { rv = vm_pager_get_pages(tobj, &tpg, 1, 0); tpg = vm_page_lookup(tobj, idx); @@ -597,8 +593,8 @@ tmpfs_mappedwrite(vm_object_t tobj, size } } else vm_page_zero_invalid(tpg, TRUE); - vm_page_wakeup(tpg); } + vm_page_wakeup(tpg); vm_page_io_start(tpg); VM_OBJECT_WUNLOCK(tobj); error = uiomove_fromphys(&tpg, offset, tlen, uio); Modified: user/attilio/vmobj-readlock/sys/kern/kern_exec.c ============================================================================== --- user/attilio/vmobj-readlock/sys/kern/kern_exec.c Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/kern/kern_exec.c Thu Jun 20 21:50:04 2013 (r252046) @@ -937,10 +937,8 @@ exec_map_first_page(imgp) object->pg_color = 0; } #endif - ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY | - VM_ALLOC_RETRY); + ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (ma[0]->valid != VM_PAGE_BITS_ALL) { - vm_page_busy(ma[0]); initial_pagein = VM_INITIAL_PAGEIN; if (initial_pagein > object->size) initial_pagein = object->size; @@ -970,9 +968,9 @@ exec_map_first_page(imgp) VM_OBJECT_WUNLOCK(object); return (EIO); } - vm_page_wakeup(ma[0]); } vm_page_lock(ma[0]); + vm_page_wakeup_locked(ma[0]); vm_page_hold(ma[0]); vm_page_unlock(ma[0]); VM_OBJECT_WUNLOCK(object); Modified: user/attilio/vmobj-readlock/sys/vm/vm_page.c ============================================================================== --- user/attilio/vmobj-readlock/sys/vm/vm_page.c Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/vm/vm_page.c Thu Jun 20 21:50:04 2013 (r252046) @@ -1258,6 +1258,7 @@ vm_page_is_cached(vm_object_t object, vm * VM_ALLOC_NODUMP do not include the page in a kernel core dump * VM_ALLOC_NOOBJ page is not associated with an object and * should not have the flag VPO_BUSY set + * VM_ALLOC_RBUSY read busy the allocated page * VM_ALLOC_WIRED wire the allocated page * VM_ALLOC_ZERO prefer a zeroed page * @@ -1272,8 +1273,12 @@ vm_page_alloc(vm_object_t object, vm_pin int flags, req_class; mpred = 0; /* XXX: pacify gcc */ - KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0), - ("vm_page_alloc: inconsistent object/req")); + KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0) && + (object != NULL || (req & VM_ALLOC_RBUSY) == 0) && + ((req & (VM_ALLOC_NOBUSY | VM_ALLOC_RBUSY)) != + (VM_ALLOC_NOBUSY | VM_ALLOC_RBUSY)), + ("vm_page_alloc: inconsistent object(%p)/req(%x)", (void *)object, + req)); if (object != NULL) VM_OBJECT_ASSERT_WLOCKED(object); @@ -1398,8 +1403,10 @@ vm_page_alloc(vm_object_t object, vm_pin m->aflags = 0; m->oflags = object == NULL || (object->flags & OBJ_UNMANAGED) != 0 ? VPO_UNMANAGED : 0; - if ((req & (VM_ALLOC_NOBUSY | VM_ALLOC_NOOBJ)) == 0) + if ((req & (VM_ALLOC_NOBUSY | VM_ALLOC_NOOBJ | VM_ALLOC_RBUSY)) == 0) m->oflags |= VPO_BUSY; + if ((req & VM_ALLOC_RBUSY) != 0) + m->busy++; if (req & VM_ALLOC_WIRED) { /* * The page lock is not required for wiring a page until that @@ -1470,6 +1477,7 @@ vm_page_alloc(vm_object_t object, vm_pin * VM_ALLOC_NOBUSY do not set the flag VPO_BUSY on the page * VM_ALLOC_NOOBJ page is not associated with an object and * should not have the flag VPO_BUSY set + * VM_ALLOC_RBUSY read busy the allocated page * VM_ALLOC_WIRED wire the allocated page * VM_ALLOC_ZERO prefer a zeroed page * @@ -1485,8 +1493,12 @@ vm_page_alloc_contig(vm_object_t object, u_int flags, oflags; int req_class; - KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0), - ("vm_page_alloc_contig: inconsistent object/req")); + KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0) && + (object != NULL || (req & VM_ALLOC_RBUSY) == 0) && + ((req & (VM_ALLOC_NOBUSY | VM_ALLOC_RBUSY)) != + (VM_ALLOC_NOBUSY | VM_ALLOC_RBUSY)), + ("vm_page_alloc: inconsistent object(%p)/req(%x)", (void *)object, + req)); if (object != NULL) { VM_OBJECT_ASSERT_WLOCKED(object); KASSERT(object->type == OBJT_PHYS, @@ -1562,7 +1574,7 @@ retry: atomic_add_int(&cnt.v_wire_count, npages); oflags = VPO_UNMANAGED; if (object != NULL) { - if ((req & VM_ALLOC_NOBUSY) == 0) + if ((req & (VM_ALLOC_NOBUSY | VM_ALLOC_RBUSY)) == 0) oflags |= VPO_BUSY; if (object->memattr != VM_MEMATTR_DEFAULT && memattr == VM_MEMATTR_DEFAULT) @@ -1571,6 +1583,8 @@ retry: for (m = m_ret; m < &m_ret[npages]; m++) { m->aflags = 0; m->flags = (m->flags | PG_NODUMP) & flags; + if ((req & VM_ALLOC_RBUSY) != 0) + m->busy++; if ((req & VM_ALLOC_WIRED) != 0) m->wire_count = 1; /* Unmanaged pages don't use "act_count". */ @@ -2422,6 +2436,9 @@ vm_page_grab(vm_object_t object, vm_pind VM_OBJECT_ASSERT_WLOCKED(object); KASSERT((allocflags & VM_ALLOC_RETRY) != 0, ("vm_page_grab: VM_ALLOC_RETRY is required")); + KASSERT((allocflags & VM_ALLOC_RBUSY) == 0 || + (allocflags & VM_ALLOC_IGN_RBUSY) != 0, + ("vm_page_grab: VM_ALLOC_RBUSY/VM_ALLOC_IGN_RBUSY mismatch")); retrylookup: if ((m = vm_page_lookup(object, pindex)) != NULL) { if ((m->oflags & VPO_BUSY) != 0 || @@ -2443,8 +2460,11 @@ retrylookup: vm_page_wire(m); vm_page_unlock(m); } - if ((allocflags & VM_ALLOC_NOBUSY) == 0) + if ((allocflags & + (VM_ALLOC_NOBUSY | VM_ALLOC_RBUSY)) == 0) vm_page_busy(m); + if ((allocflags & VM_ALLOC_RBUSY) != 0) + vm_page_io_start(m); return (m); } } Modified: user/attilio/vmobj-readlock/sys/vm/vm_page.h ============================================================================== --- user/attilio/vmobj-readlock/sys/vm/vm_page.h Thu Jun 20 21:38:08 2013 (r252045) +++ user/attilio/vmobj-readlock/sys/vm/vm_page.h Thu Jun 20 21:50:04 2013 (r252046) @@ -348,6 +348,7 @@ vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa) #define VM_ALLOC_IFNOTCACHED 0x0800 /* Fail if the page is cached */ #define VM_ALLOC_IGN_RBUSY 0x1000 /* vm_page_grab() only */ #define VM_ALLOC_NODUMP 0x2000 /* don't include in dump */ +#define VM_ALLOC_RBUSY 0x4000 /* Read busy the page */ #define VM_ALLOC_COUNT_SHIFT 16 #define VM_ALLOC_COUNT(count) ((count) << VM_ALLOC_COUNT_SHIFT)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306202150.r5KLo401090325>