svn commit: r322571 - head/sys/vm
Ruslan Bukin
br at FreeBSD.org
Wed Aug 16 08:49:13 UTC 2017
Author: br
Date: Wed Aug 16 08:49:11 2017
New Revision: 322571
URL: https://svnweb.freebsd.org/changeset/base/322571
Log:
Add OBJ_PG_DTOR flag to VM object.
Setting this flag allows us to skip pages removal from VM object queue
during object termination and to leave that for cdev_pg_dtor function.
Move pages removal code to separate function vm_object_terminate_pages()
as comments does not survive indentation.
This will be required for Intel SGX support where we will have to remove
pages from VM object manually.
Reviewed by: kib, alc
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D11688
Modified:
head/sys/vm/vm_object.c
head/sys/vm/vm_object.h
Modified: head/sys/vm/vm_object.c
==============================================================================
--- head/sys/vm/vm_object.c Wed Aug 16 08:19:44 2017 (r322570)
+++ head/sys/vm/vm_object.c Wed Aug 16 08:49:11 2017 (r322571)
@@ -694,6 +694,54 @@ vm_object_destroy(vm_object_t object)
}
/*
+ * vm_object_terminate_pages removes any remaining pageable pages
+ * from the object and resets the object to an empty state.
+ */
+static void
+vm_object_terminate_pages(vm_object_t object)
+{
+ vm_page_t p, p_next;
+
+ VM_OBJECT_ASSERT_WLOCKED(object);
+
+ /*
+ * Free any remaining pageable pages. This also removes them from the
+ * paging queues. However, don't free wired pages, just remove them
+ * from the object. Rather than incrementally removing each page from
+ * the object, the page and object are reset to any empty state.
+ */
+ TAILQ_FOREACH_SAFE(p, &object->memq, listq, p_next) {
+ vm_page_assert_unbusied(p);
+ vm_page_lock(p);
+ /*
+ * Optimize the page's removal from the object by resetting
+ * its "object" field. Specifically, if the page is not
+ * wired, then the effect of this assignment is that
+ * vm_page_free()'s call to vm_page_remove() will return
+ * immediately without modifying the page or the object.
+ */
+ p->object = NULL;
+ if (p->wire_count == 0) {
+ vm_page_free(p);
+ VM_CNT_INC(v_pfree);
+ }
+ vm_page_unlock(p);
+ }
+ /*
+ * If the object contained any pages, then reset it to an empty state.
+ * None of the object's fields, including "resident_page_count", were
+ * modified by the preceding loop.
+ */
+ if (object->resident_page_count != 0) {
+ vm_radix_reclaim_allnodes(&object->rtree);
+ TAILQ_INIT(&object->memq);
+ object->resident_page_count = 0;
+ if (object->type == OBJT_VNODE)
+ vdrop(object->handle);
+ }
+}
+
+/*
* vm_object_terminate actually destroys the specified object, freeing
* up all previously used resources.
*
@@ -703,7 +751,6 @@ vm_object_destroy(vm_object_t object)
void
vm_object_terminate(vm_object_t object)
{
- vm_page_t p, p_next;
VM_OBJECT_ASSERT_WLOCKED(object);
@@ -746,41 +793,8 @@ vm_object_terminate(vm_object_t object)
("vm_object_terminate: object with references, ref_count=%d",
object->ref_count));
- /*
- * Free any remaining pageable pages. This also removes them from the
- * paging queues. However, don't free wired pages, just remove them
- * from the object. Rather than incrementally removing each page from
- * the object, the page and object are reset to any empty state.
- */
- TAILQ_FOREACH_SAFE(p, &object->memq, listq, p_next) {
- vm_page_assert_unbusied(p);
- vm_page_lock(p);
- /*
- * Optimize the page's removal from the object by resetting
- * its "object" field. Specifically, if the page is not
- * wired, then the effect of this assignment is that
- * vm_page_free()'s call to vm_page_remove() will return
- * immediately without modifying the page or the object.
- */
- p->object = NULL;
- if (p->wire_count == 0) {
- vm_page_free(p);
- VM_CNT_INC(v_pfree);
- }
- vm_page_unlock(p);
- }
- /*
- * If the object contained any pages, then reset it to an empty state.
- * None of the object's fields, including "resident_page_count", were
- * modified by the preceding loop.
- */
- if (object->resident_page_count != 0) {
- vm_radix_reclaim_allnodes(&object->rtree);
- TAILQ_INIT(&object->memq);
- object->resident_page_count = 0;
- if (object->type == OBJT_VNODE)
- vdrop(object->handle);
- }
+ if ((object->flags & OBJ_PG_DTOR) == 0)
+ vm_object_terminate_pages(object);
#if VM_NRESERVLEVEL > 0
if (__predict_false(!LIST_EMPTY(&object->rvq)))
Modified: head/sys/vm/vm_object.h
==============================================================================
--- head/sys/vm/vm_object.h Wed Aug 16 08:19:44 2017 (r322570)
+++ head/sys/vm/vm_object.h Wed Aug 16 08:49:11 2017 (r322571)
@@ -175,6 +175,7 @@ struct vm_object {
#define OBJ_NOSPLIT 0x0010 /* dont split this object */
#define OBJ_UMTXDEAD 0x0020 /* umtx pshared was terminated */
#define OBJ_PIPWNT 0x0040 /* paging in progress wanted */
+#define OBJ_PG_DTOR 0x0080 /* dont reset object, leave that for dtor */
#define OBJ_MIGHTBEDIRTY 0x0100 /* object might be dirty, only for vnode */
#define OBJ_TMPFS_NODE 0x0200 /* object belongs to tmpfs VREG node */
#define OBJ_TMPFS_DIRTY 0x0400 /* dirty tmpfs obj */
More information about the svn-src-all
mailing list