Skip site navigation (1)Skip section navigation (2)
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>