summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2015-09-09 23:33:38 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2015-09-09 23:33:38 +0000
commit1c7fab06cc8bb849d0d5e440cfd6f5af82204cf0 (patch)
tree51f2c5666435425e4b6ecc42d84c46b824a0f5bc
parent28407fd2d1c7ecd529eb9e663ec4d75f8c58f638 (diff)
Add locking for interrupt-safe maps (those that have the VM_MAP_INTRSAFE flag
set). Since we cannot sleep in that case, use a mutex instead of an rwlock. This is ok as the more complex code paths in the uvm code are not entered for interrupt-safe maps as paging isn't allowed in those maps. ok tedu@
-rw-r--r--sys/uvm/uvm_map.c17
-rw-r--r--sys/uvm/uvm_map.h3
2 files changed, 17 insertions, 3 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index 0e846ff5832..9c51fa1478c 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.197 2015/09/09 14:52:12 miod Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.198 2015/09/09 23:33:37 kettenis Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -2392,6 +2392,7 @@ uvm_map_setup(struct vm_map *map, vaddr_t min, vaddr_t max, int flags)
map->flags = flags;
map->timestamp = 0;
rw_init(&map->lock, "vmmaplk");
+ mtx_init(&map->mtx, IPL_VM);
mtx_init(&map->flags_lock, IPL_VM);
/* Configure the allocators. */
@@ -4949,7 +4950,7 @@ vm_map_lock_try_ln(struct vm_map *map, char *file, int line)
boolean_t rv;
if (map->flags & VM_MAP_INTRSAFE) {
- rv = TRUE;
+ rv = mtx_enter_try(&map->mtx);
} else {
mtx_enter(&map->flags_lock);
if (map->flags & VM_MAP_BUSY) {
@@ -5000,6 +5001,8 @@ tryagain:
goto tryagain;
}
mtx_leave(&map->flags_lock);
+ } else {
+ mtx_enter(&map->mtx);
}
map->timestamp++;
@@ -5013,6 +5016,8 @@ vm_map_lock_read_ln(struct vm_map *map, char *file, int line)
{
if ((map->flags & VM_MAP_INTRSAFE) == 0)
rw_enter_read(&map->lock);
+ else
+ mtx_enter(&map->mtx);
LPRINTF(("map lock: %p (at %s %d)\n", map, file, line));
uvm_tree_sanity(map, file, line);
uvm_tree_size_chk(map, file, line);
@@ -5026,6 +5031,8 @@ vm_map_unlock_ln(struct vm_map *map, char *file, int line)
LPRINTF(("map unlock: %p (at %s %d)\n", map, file, line));
if ((map->flags & VM_MAP_INTRSAFE) == 0)
rw_exit(&map->lock);
+ else
+ mtx_leave(&map->mtx);
}
void
@@ -5036,6 +5043,8 @@ vm_map_unlock_read_ln(struct vm_map *map, char *file, int line)
LPRINTF(("map unlock: %p (at %s %d)\n", map, file, line));
if ((map->flags & VM_MAP_INTRSAFE) == 0)
rw_exit_read(&map->lock);
+ else
+ mtx_leave(&map->mtx);
}
void
@@ -5045,6 +5054,7 @@ vm_map_downgrade_ln(struct vm_map *map, char *file, int line)
uvm_tree_size_chk(map, file, line);
LPRINTF(("map unlock: %p (at %s %d)\n", map, file, line));
LPRINTF(("map lock: %p (at %s %d)\n", map, file, line));
+ KASSERT((map->flags & VM_MAP_INTRSAFE) == 0);
if ((map->flags & VM_MAP_INTRSAFE) == 0)
rw_enter(&map->lock, RW_DOWNGRADE);
}
@@ -5055,6 +5065,7 @@ vm_map_upgrade_ln(struct vm_map *map, char *file, int line)
/* XXX: RO */ uvm_tree_sanity(map, file, line);
/* XXX: RO */ uvm_tree_size_chk(map, file, line);
LPRINTF(("map unlock: %p (at %s %d)\n", map, file, line));
+ KASSERT((map->flags & VM_MAP_INTRSAFE) == 0);
if ((map->flags & VM_MAP_INTRSAFE) == 0) {
rw_exit_read(&map->lock);
rw_enter_write(&map->lock);
@@ -5066,6 +5077,7 @@ vm_map_upgrade_ln(struct vm_map *map, char *file, int line)
void
vm_map_busy_ln(struct vm_map *map, char *file, int line)
{
+ KASSERT((map->flags & VM_MAP_INTRSAFE) == 0);
mtx_enter(&map->flags_lock);
map->flags |= VM_MAP_BUSY;
mtx_leave(&map->flags_lock);
@@ -5076,6 +5088,7 @@ vm_map_unbusy_ln(struct vm_map *map, char *file, int line)
{
int oflags;
+ KASSERT((map->flags & VM_MAP_INTRSAFE) == 0);
mtx_enter(&map->flags_lock);
oflags = map->flags;
map->flags &= ~(VM_MAP_BUSY|VM_MAP_WANTLOCK);
diff --git a/sys/uvm/uvm_map.h b/sys/uvm/uvm_map.h
index c23e070f703..38604b577d6 100644
--- a/sys/uvm/uvm_map.h
+++ b/sys/uvm/uvm_map.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.h,v 1.54 2015/03/30 21:08:40 miod Exp $ */
+/* $OpenBSD: uvm_map.h,v 1.55 2015/09/09 23:33:37 kettenis Exp $ */
/* $NetBSD: uvm_map.h,v 1.24 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -288,6 +288,7 @@ RB_PROTOTYPE(uvm_map_addr, vm_map_entry, daddrs.addr_entry,
struct vm_map {
struct pmap * pmap; /* Physical map */
struct rwlock lock; /* Lock for map data */
+ struct mutex mtx;
struct uvm_map_addr addr; /* Entry tree, by addr */