Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135179654
D9282.id24410.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D9282.id24410.diff
View Options
Index: sys/vm/vm_object.c
===================================================================
--- sys/vm/vm_object.c
+++ sys/vm/vm_object.c
@@ -1074,6 +1074,27 @@
return (res);
}
+static bool
+vm_object_advice_applies(vm_object_t object, int advice)
+{
+
+ if ((object->flags & OBJ_UNMANAGED) != 0)
+ return (false);
+ if (advice != MADV_FREE)
+ return (true);
+ return ((object->type == OBJT_DEFAULT || object->type == OBJT_SWAP) &&
+ (object->flags & OBJ_ONEMAPPING) != 0);
+}
+
+static void
+vm_object_madvise_freespace(vm_object_t object, int advice, vm_pindex_t pindex,
+ vm_size_t size)
+{
+
+ if (advice == MADV_FREE && object->type == OBJT_SWAP)
+ swap_pager_freespace(object, pindex, size);
+}
+
/*
* vm_object_madvise:
*
@@ -1101,100 +1122,104 @@
{
vm_pindex_t tpindex;
vm_object_t backing_object, tobject;
- vm_page_t m;
+ vm_page_t m, tm;
if (object == NULL)
return;
- VM_OBJECT_WLOCK(object);
- for (m = NULL; pindex < end; pindex++) {
relookup:
+ VM_OBJECT_WLOCK(object);
+ if (!vm_object_advice_applies(object, advice)) {
+ VM_OBJECT_WUNLOCK(object);
+ return;
+ }
+ for (m = vm_page_find_least(object, pindex); pindex < end; pindex++) {
tobject = object;
- tpindex = pindex;
-shadowlookup:
- /*
- * MADV_FREE only operates on OBJT_DEFAULT or OBJT_SWAP pages
- * and those pages must be OBJ_ONEMAPPING.
- */
- if (advice == MADV_FREE) {
- if ((tobject->type != OBJT_DEFAULT &&
- tobject->type != OBJT_SWAP) ||
- (tobject->flags & OBJ_ONEMAPPING) == 0) {
- goto unlock_tobject;
- }
- } else if ((tobject->flags & OBJ_UNMANAGED) != 0)
- goto unlock_tobject;
/*
- * In the common case where the object has no backing object, we
- * can avoid performing lookups at each pindex. In either case,
- * when applying MADV_FREE we take care to release any swap
- * space used to store non-resident pages.
+ * If the next page isn't resident in the top-level object, we
+ * need to search the shadow chain. When applying MADV_FREE, we
+ * take care to release any swap space used to store
+ * non-resident pages.
*/
- if (object->backing_object == NULL) {
- m = (m != NULL) ? TAILQ_NEXT(m, listq) :
- vm_page_find_least(object, pindex);
- tpindex = (m != NULL && m->pindex < end) ?
- m->pindex : end;
- if (advice == MADV_FREE && object->type == OBJT_SWAP &&
- tpindex > pindex)
- swap_pager_freespace(object, pindex,
- tpindex - pindex);
- if ((pindex = tpindex) == end)
- break;
- } else if ((m = vm_page_lookup(tobject, tpindex)) == NULL) {
- if (advice == MADV_FREE && tobject->type == OBJT_SWAP)
- swap_pager_freespace(tobject, tpindex, 1);
+ if (m == NULL || pindex < m->pindex) {
/*
- * Prepare to search the next object in the chain.
+ * Optimize a common special case: if the top-level
+ * object has no backing object, we can skip over the
+ * non-resident range in constant time.
*/
- backing_object = tobject->backing_object;
- if (backing_object == NULL)
- goto unlock_tobject;
- VM_OBJECT_WLOCK(backing_object);
- tpindex += OFF_TO_IDX(tobject->backing_object_offset);
- if (tobject != object)
- VM_OBJECT_WUNLOCK(tobject);
- tobject = backing_object;
- goto shadowlookup;
+ if (object->backing_object == NULL) {
+ tpindex = (m != NULL && m->pindex < end) ?
+ m->pindex : end;
+ vm_object_madvise_freespace(object, advice,
+ pindex, tpindex - pindex);
+ if ((pindex = tpindex) == end)
+ break;
+ goto next_page;
+ }
+
+ tm = NULL;
+ tpindex = pindex;
+ do {
+ MPASS(tm == NULL || tm->object != object);
+ vm_object_madvise_freespace(tobject, advice,
+ tpindex, 1);
+ /*
+ * Prepare to search the next object in the
+ * chain.
+ */
+ backing_object = tobject->backing_object;
+ if (backing_object == NULL)
+ goto next_pindex;
+ VM_OBJECT_WLOCK(backing_object);
+ tpindex +=
+ OFF_TO_IDX(tobject->backing_object_offset);
+ if (tobject != object)
+ VM_OBJECT_WUNLOCK(tobject);
+ tobject = backing_object;
+ if (!vm_object_advice_applies(tobject, advice))
+ goto next_pindex;
+ } while ((tm = vm_page_lookup(tobject, tpindex)) ==
+ NULL);
+ } else {
+next_page:
+ tm = m;
+ m = TAILQ_NEXT(m, listq);
}
/*
* If the page is not in a normal state, skip it.
*/
- if (m->valid != VM_PAGE_BITS_ALL)
- goto unlock_tobject;
- vm_page_lock(m);
- if (m->hold_count != 0 || m->wire_count != 0) {
- vm_page_unlock(m);
- goto unlock_tobject;
+ if (tm->valid != VM_PAGE_BITS_ALL)
+ goto next_pindex;
+ vm_page_lock(tm);
+ if (tm->hold_count != 0 || tm->wire_count != 0) {
+ vm_page_unlock(tm);
+ goto next_pindex;
}
- KASSERT((m->flags & PG_FICTITIOUS) == 0,
- ("vm_object_madvise: page %p is fictitious", m));
- KASSERT((m->oflags & VPO_UNMANAGED) == 0,
- ("vm_object_madvise: page %p is not managed", m));
- if (vm_page_busied(m)) {
+ KASSERT((tm->flags & PG_FICTITIOUS) == 0,
+ ("vm_object_madvise: page %p is fictitious", tm));
+ KASSERT((tm->oflags & VPO_UNMANAGED) == 0,
+ ("vm_object_madvise: page %p is not managed", tm));
+ if (vm_page_busied(tm)) {
+ if (object != tobject)
+ VM_OBJECT_WUNLOCK(tobject);
+ VM_OBJECT_WUNLOCK(object);
if (advice == MADV_WILLNEED) {
/*
* Reference the page before unlocking and
* sleeping so that the page daemon is less
- * likely to reclaim it.
+ * likely to reclaim it.
*/
- vm_page_aflag_set(m, PGA_REFERENCED);
+ vm_page_aflag_set(tm, PGA_REFERENCED);
}
- if (object != tobject)
- VM_OBJECT_WUNLOCK(object);
- VM_OBJECT_WUNLOCK(tobject);
- vm_page_busy_sleep(m, "madvpo", false);
- m = NULL;
- VM_OBJECT_WLOCK(object);
+ vm_page_busy_sleep(tm, "madvpo", false);
goto relookup;
}
- vm_page_advise(m, advice);
- vm_page_unlock(m);
- if (advice == MADV_FREE && tobject->type == OBJT_SWAP)
- swap_pager_freespace(tobject, tpindex, 1);
-unlock_tobject:
+ vm_page_advise(tm, advice);
+ vm_page_unlock(tm);
+ vm_object_madvise_freespace(tobject, advice, tm->pindex, 1);
+next_pindex:
if (tobject != object)
VM_OBJECT_WUNLOCK(tobject);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 8, 5:20 AM (6 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25028242
Default Alt Text
D9282.id24410.diff (6 KB)
Attached To
Mode
D9282: Further optimize vm_object_madvise()
Attached
Detach File
Event Timeline
Log In to Comment