summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>1999-08-13 17:45:34 +0000
committeralc <alc@FreeBSD.org>1999-08-13 17:45:34 +0000
commit7fd2f69ac581f1906241fcb53d9bd2dae40f7c24 (patch)
treebeb1998148d32fff8920918c61b627970a8f74a6 /sys/vm/vm_map.c
parenta9521339a7bd807b0dae35b4b70a0150df0bcd24 (diff)
downloadFreeBSD-src-7fd2f69ac581f1906241fcb53d9bd2dae40f7c24.zip
FreeBSD-src-7fd2f69ac581f1906241fcb53d9bd2dae40f7c24.tar.gz
vm_map_madvise:
A complete rewrite by dillon and myself to separate the implementation of behaviors that effect the vm_map_entry from those that effect the vm_object. A result of this change is that madvise(..., MADV_FREE); is much cheaper.
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c145
1 files changed, 85 insertions, 60 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 8fd5eb7..6ea4395 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.c,v 1.174 1999/08/01 06:05:08 alc Exp $
+ * $Id: vm_map.c,v 1.175 1999/08/10 04:50:20 alc Exp $
*/
/*
@@ -1005,88 +1005,113 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
* vm_map_madvise:
*
* This routine traverses a processes map handling the madvise
- * system call.
+ * system call. Advisories are classified as either those effecting
+ * the vm_map_entry structure, or those effecting the underlying
+ * objects.
*/
void
-vm_map_madvise(map, start, end, advise)
+vm_map_madvise(map, start, end, behav)
vm_map_t map;
vm_offset_t start, end;
- int advise;
+ int behav;
{
- vm_map_entry_t current;
- vm_map_entry_t entry;
+ vm_map_entry_t current, entry;
+ int modify_map;
- vm_map_lock(map);
+ modify_map = (behav == MADV_NORMAL || behav == MADV_SEQUENTIAL ||
+ behav == MADV_RANDOM);
+
+ if (modify_map) {
+ vm_map_lock(map);
+ }
+ else
+ vm_map_lock_read(map);
VM_MAP_RANGE_CHECK(map, start, end);
if (vm_map_lookup_entry(map, start, &entry)) {
- vm_map_clip_start(map, entry, start);
+ if (modify_map)
+ vm_map_clip_start(map, entry, start);
} else
entry = entry->next;
- for(current = entry;
- (current != &map->header) && (current->start < end);
- current = current->next) {
+ if (modify_map) {
+ /*
+ * madvise behaviors that are implemented in the vm_map_entry.
+ *
+ * We clip the vm_map_entry so that behavioral changes are
+ * limited to the specified address range.
+ */
+ for (current = entry;
+ (current != &map->header) && (current->start < end);
+ current = current->next) {
- if (current->eflags & MAP_ENTRY_IS_SUB_MAP) {
- continue;
+ if (current->eflags & MAP_ENTRY_IS_SUB_MAP)
+ continue;
+
+ vm_map_clip_end(map, current, end);
+
+ switch (behav) {
+ case MADV_NORMAL:
+ vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_NORMAL);
+ break;
+ case MADV_SEQUENTIAL:
+ vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_SEQUENTIAL);
+ break;
+ case MADV_RANDOM:
+ vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_RANDOM);
+ break;
+ default:
+ break;
+ }
+ vm_map_simplify_entry(map, current);
}
+ vm_map_unlock(map);
+ }
+ else {
+ if (behav == MADV_FREE || behav == MADV_DONTNEED ||
+ behav == MADV_WILLNEED) {
+ vm_pindex_t pindex;
+ int count;
- vm_map_clip_end(map, current, end);
+ /*
+ * madvise behaviors that are implemented in the underlying
+ * vm_object.
+ *
+ * Since we don't clip the vm_map_entry, we have to clip
+ * the vm_object pindex and count.
+ */
+ for (current = entry;
+ (current != &map->header) && (current->start < end);
+ current = current->next) {
- switch (advise) {
- case MADV_NORMAL:
- vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_NORMAL);
- break;
- case MADV_SEQUENTIAL:
- vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_SEQUENTIAL);
- break;
- case MADV_RANDOM:
- vm_map_entry_set_behavior(current, MAP_ENTRY_BEHAV_RANDOM);
- break;
- /*
- * Right now, we could handle DONTNEED and WILLNEED with common code.
- * They are mostly the same, except for the potential async reads (NYI).
- */
- case MADV_FREE:
- case MADV_DONTNEED:
- {
- vm_pindex_t pindex;
- int count;
- pindex = OFF_TO_IDX(current->offset);
- count = OFF_TO_IDX(current->end - current->start);
- /*
- * MADV_DONTNEED removes the page from all
- * pmaps, so pmap_remove is not necessary.
- */
- vm_object_madvise(current->object.vm_object,
- pindex, count, advise);
- }
- break;
+ if (current->eflags & MAP_ENTRY_IS_SUB_MAP)
+ continue;
- case MADV_WILLNEED:
- {
- vm_pindex_t pindex;
- int count;
pindex = OFF_TO_IDX(current->offset);
- count = OFF_TO_IDX(current->end - current->start);
+ count = atop(current->end - current->start);
+
+ if (current->start < start) {
+ pindex += atop(start - current->start);
+ count -= atop(start - current->start);
+ }
+ if (current->end > end)
+ count -= atop(current->end - end);
+
+ if (count <= 0)
+ continue;
+
vm_object_madvise(current->object.vm_object,
- pindex, count, advise);
- pmap_object_init_pt(map->pmap, current->start,
- current->object.vm_object, pindex,
- (count << PAGE_SHIFT), 0);
+ pindex, count, behav);
+ if (behav == MADV_WILLNEED)
+ pmap_object_init_pt(map->pmap, current->start,
+ current->object.vm_object,
+ pindex, (count << PAGE_SHIFT),
+ 0);
}
- break;
-
- default:
- break;
}
+ vm_map_unlock_read(map);
}
-
- vm_map_simplify_entry(map, entry);
- vm_map_unlock(map);
- return;
}
OpenPOWER on IntegriCloud