summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>1999-03-07 21:25:42 +0000
committeralc <alc@FreeBSD.org>1999-03-07 21:25:42 +0000
commit65b8ae094477c6bee23ab43fa32dba44f3b9fd75 (patch)
tree47361a3fb9f3beaf6573a71c32275037cbcdb3d5 /sys/vm
parente36037abffd75e59c147b7ff7f223a2763b1cd60 (diff)
downloadFreeBSD-src-65b8ae094477c6bee23ab43fa32dba44f3b9fd75.zip
FreeBSD-src-65b8ae094477c6bee23ab43fa32dba44f3b9fd75.tar.gz
Change vm_map_growstack to acquire and hold a read lock (instead of a write
lock) until it actually needs to modify the vm_map. Note: it is legal to modify vm_map::hint without holding a write lock. Submitted by: "Richard Seaman, Jr." <dick@tar.com> with minor changes by myself.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_map.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 4f6a359..b449ed0 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.152 1999/02/24 21:26:25 dillon Exp $
+ * $Id: vm_map.c,v 1.153 1999/03/02 05:43:17 alc Exp $
*/
/*
@@ -659,18 +659,18 @@ vm_map_growstack (struct proc *p, vm_offset_t addr)
vm_offset_t end;
int grow_amount;
int rv;
- int is_procstack = 0;
-
- vm_map_lock(map);
+ int is_procstack;
+Retry:
+ vm_map_lock_read(map);
/* If addr is already in the entry range, no need to grow.*/
if (vm_map_lookup_entry(map, addr, &prev_entry)) {
- vm_map_unlock(map);
+ vm_map_unlock_read(map);
return (KERN_SUCCESS);
}
if ((stack_entry = prev_entry->next) == &map->header) {
- vm_map_unlock(map);
+ vm_map_unlock_read(map);
return (KERN_SUCCESS);
}
if (prev_entry == &map->header)
@@ -688,14 +688,14 @@ vm_map_growstack (struct proc *p, vm_offset_t addr)
if (stack_entry->avail_ssize < 1 ||
addr >= stack_entry->start ||
addr < stack_entry->start - stack_entry->avail_ssize) {
- vm_map_unlock(map);
+ vm_map_unlock_read(map);
return (KERN_SUCCESS);
}
/* Find the minimum grow amount */
grow_amount = roundup (stack_entry->start - addr, PAGE_SIZE);
if (grow_amount > stack_entry->avail_ssize) {
- vm_map_unlock(map);
+ vm_map_unlock_read(map);
return (KERN_NO_SPACE);
}
@@ -709,20 +709,23 @@ vm_map_growstack (struct proc *p, vm_offset_t addr)
* might have intended by limiting the stack size.
*/
if (grow_amount > stack_entry->start - end) {
+ if (vm_map_lock_upgrade(map))
+ goto Retry;
+
stack_entry->avail_ssize = stack_entry->start - end;
+
vm_map_unlock(map);
return (KERN_NO_SPACE);
}
- if (addr >= (vm_offset_t)vm->vm_maxsaddr)
- is_procstack = 1;
+ is_procstack = addr >= (vm_offset_t)vm->vm_maxsaddr;
/* If this is the main process stack, see if we're over the
* stack limit.
*/
if (is_procstack && (vm->vm_ssize + grow_amount >
p->p_rlimit[RLIMIT_STACK].rlim_cur)) {
- vm_map_unlock(map);
+ vm_map_unlock_read(map);
return (KERN_NO_SPACE);
}
@@ -737,6 +740,9 @@ vm_map_growstack (struct proc *p, vm_offset_t addr)
vm->vm_ssize;
}
+ if (vm_map_lock_upgrade(map))
+ goto Retry;
+
/* Get the preliminary new entry start value */
addr = stack_entry->start - grow_amount;
OpenPOWER on IntegriCloud