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
Attilio Rao
attilio at FreeBSD.org
Thu Jun 20 21:50:06 UTC 2013
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)
More information about the svn-src-user
mailing list