Revert the addition of the freelist argument for the vm_map_delete()

function, done in r188334. Instead, collect the entries that shall be
freed, in the deferred_freelist member of the map. Automatically purge
the deferred freelist when map is unlocked.

Tested by:	pho
Reviewed by:	alc
This commit is contained in:
kib 2009-02-24 20:57:43 +00:00
parent 47de55da04
commit 66c697aade
5 changed files with 31 additions and 50 deletions

View File

@ -272,7 +272,7 @@ kmem_malloc(map, size, flags)
int flags; int flags;
{ {
vm_offset_t offset, i; vm_offset_t offset, i;
vm_map_entry_t entry, freelist; vm_map_entry_t entry;
vm_offset_t addr; vm_offset_t addr;
vm_page_t m; vm_page_t m;
int pflags; int pflags;
@ -356,10 +356,8 @@ kmem_malloc(map, size, flags)
vm_page_unlock_queues(); vm_page_unlock_queues();
} }
VM_OBJECT_UNLOCK(kmem_object); VM_OBJECT_UNLOCK(kmem_object);
freelist = NULL; vm_map_delete(map, addr, addr + size);
vm_map_delete(map, addr, addr + size, &freelist);
vm_map_unlock(map); vm_map_unlock(map);
vm_map_entry_free_freelist(map, freelist);
return (0); return (0);
} }
if (flags & M_ZERO && (m->flags & PG_ZERO) == 0) if (flags & M_ZERO && (m->flags & PG_ZERO) == 0)
@ -458,18 +456,14 @@ kmem_free_wakeup(map, addr, size)
vm_offset_t addr; vm_offset_t addr;
vm_size_t size; vm_size_t size;
{ {
vm_map_entry_t freelist;
freelist = NULL;
vm_map_lock(map); vm_map_lock(map);
(void) vm_map_delete(map, trunc_page(addr), round_page(addr + size), (void) vm_map_delete(map, trunc_page(addr), round_page(addr + size));
&freelist);
if (map->needs_wakeup) { if (map->needs_wakeup) {
map->needs_wakeup = FALSE; map->needs_wakeup = FALSE;
vm_map_wakeup(map); vm_map_wakeup(map);
} }
vm_map_unlock(map); vm_map_unlock(map);
vm_map_entry_free_freelist(map, freelist);
} }
/* /*

View File

@ -143,7 +143,7 @@ static void vmspace_zfini(void *mem, int size);
static int vm_map_zinit(void *mem, int ize, int flags); static int vm_map_zinit(void *mem, int ize, int flags);
static void vm_map_zfini(void *mem, int size); static void vm_map_zfini(void *mem, int size);
static void _vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max); static void _vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max);
static void vm_map_entry_dispose(vm_map_t map, vm_map_entry_t entry);
#ifdef INVARIANTS #ifdef INVARIANTS
static void vm_map_zdtor(void *mem, int size, void *arg); static void vm_map_zdtor(void *mem, int size, void *arg);
static void vmspace_zdtor(void *mem, int size, void *arg); static void vmspace_zdtor(void *mem, int size, void *arg);
@ -456,11 +456,28 @@ _vm_map_lock(vm_map_t map, const char *file, int line)
void void
_vm_map_unlock(vm_map_t map, const char *file, int line) _vm_map_unlock(vm_map_t map, const char *file, int line)
{ {
vm_map_entry_t free_entry, entry;
vm_object_t object;
free_entry = map->deferred_freelist;
map->deferred_freelist = NULL;
if (map->system_map) if (map->system_map)
_mtx_unlock_flags(&map->system_mtx, 0, file, line); _mtx_unlock_flags(&map->system_mtx, 0, file, line);
else else
_sx_xunlock(&map->lock, file, line); _sx_xunlock(&map->lock, file, line);
while (free_entry != NULL) {
entry = free_entry;
free_entry = free_entry->next;
if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) {
object = entry->object.vm_object;
vm_object_deallocate(object);
}
vm_map_entry_dispose(map, entry);
}
} }
void void
@ -682,6 +699,7 @@ _vm_map_init(vm_map_t map, vm_offset_t min, vm_offset_t max)
map->flags = 0; map->flags = 0;
map->root = NULL; map->root = NULL;
map->timestamp = 0; map->timestamp = 0;
map->deferred_freelist = NULL;
} }
void void
@ -1297,19 +1315,16 @@ vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
vm_offset_t start, vm_size_t length, vm_prot_t prot, vm_offset_t start, vm_size_t length, vm_prot_t prot,
vm_prot_t max, int cow) vm_prot_t max, int cow)
{ {
vm_map_entry_t freelist;
vm_offset_t end; vm_offset_t end;
int result; int result;
end = start + length; end = start + length;
freelist = NULL;
vm_map_lock(map); vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end); VM_MAP_RANGE_CHECK(map, start, end);
(void) vm_map_delete(map, start, end, &freelist); (void) vm_map_delete(map, start, end);
result = vm_map_insert(map, object, offset, start, end, prot, result = vm_map_insert(map, object, offset, start, end, prot,
max, cow); max, cow);
vm_map_unlock(map); vm_map_unlock(map);
vm_map_entry_free_freelist(map, freelist);
return (result); return (result);
} }
@ -2435,23 +2450,6 @@ vm_map_entry_unwire(vm_map_t map, vm_map_entry_t entry)
entry->wired_count = 0; entry->wired_count = 0;
} }
void
vm_map_entry_free_freelist(vm_map_t map, vm_map_entry_t freelist)
{
vm_map_entry_t e;
vm_object_t object;
while (freelist != NULL) {
e = freelist;
freelist = freelist->next;
if ((e->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) {
object = e->object.vm_object;
vm_object_deallocate(object);
}
vm_map_entry_dispose(map, e);
}
}
/* /*
* vm_map_entry_delete: [ internal use only ] * vm_map_entry_delete: [ internal use only ]
* *
@ -2495,8 +2493,7 @@ vm_map_entry_delete(vm_map_t map, vm_map_entry_t entry)
* map. * map.
*/ */
int int
vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end, vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end)
vm_map_entry_t *freelist)
{ {
vm_map_entry_t entry; vm_map_entry_t entry;
vm_map_entry_t first_entry; vm_map_entry_t first_entry;
@ -2575,8 +2572,8 @@ vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end,
* will be set in the wrong object!) * will be set in the wrong object!)
*/ */
vm_map_entry_delete(map, entry); vm_map_entry_delete(map, entry);
entry->next = *freelist; entry->next = map->deferred_freelist;
*freelist = entry; map->deferred_freelist = entry;
entry = next; entry = next;
} }
return (KERN_SUCCESS); return (KERN_SUCCESS);
@ -2591,15 +2588,12 @@ vm_map_delete(vm_map_t map, vm_offset_t start, vm_offset_t end,
int int
vm_map_remove(vm_map_t map, vm_offset_t start, vm_offset_t end) vm_map_remove(vm_map_t map, vm_offset_t start, vm_offset_t end)
{ {
vm_map_entry_t freelist;
int result; int result;
freelist = NULL;
vm_map_lock(map); vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end); VM_MAP_RANGE_CHECK(map, start, end);
result = vm_map_delete(map, start, end, &freelist); result = vm_map_delete(map, start, end);
vm_map_unlock(map); vm_map_unlock(map);
vm_map_entry_free_freelist(map, freelist);
return (result); return (result);
} }

View File

@ -157,8 +157,6 @@ vm_map_entry_system_wired_count(vm_map_entry_t entry)
{ {
return (entry->wired_count - vm_map_entry_user_wired_count(entry)); return (entry->wired_count - vm_map_entry_user_wired_count(entry));
} }
void vm_map_entry_free_freelist(vm_map_t map, vm_map_entry_t freelist);
#endif /* _KERNEL */ #endif /* _KERNEL */
/* /*
@ -184,6 +182,7 @@ struct vm_map {
vm_flags_t flags; /* flags for this vm_map */ vm_flags_t flags; /* flags for this vm_map */
vm_map_entry_t root; /* Root of a binary search tree */ vm_map_entry_t root; /* Root of a binary search tree */
pmap_t pmap; /* (c) Physical map */ pmap_t pmap; /* (c) Physical map */
vm_map_entry_t deferred_freelist;
#define min_offset header.start /* (c) */ #define min_offset header.start /* (c) */
#define max_offset header.end /* (c) */ #define max_offset header.end /* (c) */
}; };
@ -338,7 +337,7 @@ long vmspace_wired_count(struct vmspace *vmspace);
#ifdef _KERNEL #ifdef _KERNEL
boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t); boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t);
vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t); vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t);
int vm_map_delete(vm_map_t, vm_offset_t, vm_offset_t, vm_map_entry_t *); int vm_map_delete(vm_map_t, vm_offset_t, vm_offset_t);
int vm_map_find(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t, int vm_map_find(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t,
int, vm_prot_t, vm_prot_t, int); int, vm_prot_t, vm_prot_t, int);
int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t, int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t,

View File

@ -552,7 +552,6 @@ munmap(td, uap)
vm_offset_t addr; vm_offset_t addr;
vm_size_t size, pageoff; vm_size_t size, pageoff;
vm_map_t map; vm_map_t map;
vm_map_entry_t freelist;
addr = (vm_offset_t) uap->addr; addr = (vm_offset_t) uap->addr;
size = uap->len; size = uap->len;
@ -572,7 +571,6 @@ munmap(td, uap)
map = &td->td_proc->p_vmspace->vm_map; map = &td->td_proc->p_vmspace->vm_map;
if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) if (addr < vm_map_min(map) || addr + size > vm_map_max(map))
return (EINVAL); return (EINVAL);
freelist = NULL;
vm_map_lock(map); vm_map_lock(map);
#ifdef HWPMC_HOOKS #ifdef HWPMC_HOOKS
/* /*
@ -595,9 +593,8 @@ munmap(td, uap)
} }
#endif #endif
/* returns nothing but KERN_SUCCESS anyway */ /* returns nothing but KERN_SUCCESS anyway */
vm_map_delete(map, addr, addr + size, &freelist); vm_map_delete(map, addr, addr + size);
vm_map_unlock(map); vm_map_unlock(map);
vm_map_entry_free_freelist(map, freelist);
return (0); return (0);
} }

View File

@ -72,7 +72,6 @@ obreak(td, uap)
struct obreak_args *uap; struct obreak_args *uap;
{ {
struct vmspace *vm = td->td_proc->p_vmspace; struct vmspace *vm = td->td_proc->p_vmspace;
vm_map_entry_t freelist;
vm_offset_t new, old, base; vm_offset_t new, old, base;
rlim_t datalim, vmemlim; rlim_t datalim, vmemlim;
int rv; int rv;
@ -86,7 +85,6 @@ obreak(td, uap)
do_map_wirefuture = FALSE; do_map_wirefuture = FALSE;
new = round_page((vm_offset_t)uap->nsize); new = round_page((vm_offset_t)uap->nsize);
freelist = NULL;
vm_map_lock(&vm->vm_map); vm_map_lock(&vm->vm_map);
base = round_page((vm_offset_t) vm->vm_daddr); base = round_page((vm_offset_t) vm->vm_daddr);
@ -140,7 +138,7 @@ obreak(td, uap)
do_map_wirefuture = TRUE; do_map_wirefuture = TRUE;
} }
} else if (new < old) { } else if (new < old) {
rv = vm_map_delete(&vm->vm_map, new, old, &freelist); rv = vm_map_delete(&vm->vm_map, new, old);
if (rv != KERN_SUCCESS) { if (rv != KERN_SUCCESS) {
error = ENOMEM; error = ENOMEM;
goto done; goto done;
@ -149,7 +147,6 @@ obreak(td, uap)
} }
done: done:
vm_map_unlock(&vm->vm_map); vm_map_unlock(&vm->vm_map);
vm_map_entry_free_freelist(&vm->vm_map, freelist);
if (do_map_wirefuture) if (do_map_wirefuture)
(void) vm_map_wire(&vm->vm_map, old, new, (void) vm_map_wire(&vm->vm_map, old, new,