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:
parent
47de55da04
commit
66c697aade
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user