summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2021-11-19 15:58:37 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2021-11-19 15:58:37 +0000
commit58626502ce382c982608c0a2314eb02a84e0a8ec (patch)
tree0be8a75c2a12dbf2c9b4888049b91c13e127b35c /sys
parent02ae592fc307256cf957d461ec057023b50e52cd (diff)
Make futexes work in shared anonymous memory.
ok mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_futex.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/sys/kern/sys_futex.c b/sys/kern/sys_futex.c
index c4cbe36364d..1cd3e714bdd 100644
--- a/sys/kern/sys_futex.c
+++ b/sys/kern/sys_futex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_futex.c,v 1.18 2021/05/26 18:11:59 kettenis Exp $ */
+/* $OpenBSD: sys_futex.c,v 1.19 2021/11/19 15:58:36 kettenis Exp $ */
/*
* Copyright (c) 2016-2017 Martin Pieuchot
@@ -49,6 +49,7 @@ struct futex {
LIST_ENTRY(futex) ft_list; /* list of all futexes */
TAILQ_HEAD(, proc) ft_threads; /* sleeping queue */
struct uvm_object *ft_obj; /* UVM object */
+ struct vm_amap *ft_amap; /* UVM amap */
voff_t ft_off; /* UVM offset */
unsigned int ft_refcnt; /* # of references */
};
@@ -144,6 +145,7 @@ futex_get(uint32_t *uaddr, int flags)
vm_map_t map = &p->p_vmspace->vm_map;
vm_map_entry_t entry;
struct uvm_object *obj = NULL;
+ struct vm_amap *amap = NULL;
voff_t off = (vaddr_t)uaddr;
struct futex *f;
struct futex_list *ftlist = &p->p_p->ps_ftlist;
@@ -153,17 +155,25 @@ futex_get(uint32_t *uaddr, int flags)
if (!(flags & FT_PRIVATE)) {
vm_map_lock_read(map);
if (uvm_map_lookup_entry(map, (vaddr_t)uaddr, &entry) &&
- UVM_ET_ISOBJ(entry) && entry->object.uvm_obj &&
entry->inheritance == MAP_INHERIT_SHARE) {
- ftlist = &ftlist_shared;
- obj = entry->object.uvm_obj;
- off = entry->offset + ((vaddr_t)uaddr - entry->start);
+ if (UVM_ET_ISOBJ(entry)) {
+ ftlist = &ftlist_shared;
+ obj = entry->object.uvm_obj;
+ off = entry->offset +
+ ((vaddr_t)uaddr - entry->start);
+ } else if (entry->aref.ar_amap) {
+ ftlist = &ftlist_shared;
+ amap = entry->aref.ar_amap;
+ off = ptoa(entry->aref.ar_pageoff) +
+ ((vaddr_t)uaddr - entry->start);
+ }
}
vm_map_unlock_read(map);
}
LIST_FOREACH(f, ftlist, ft_list) {
- if (f->ft_obj == obj && f->ft_off == off) {
+ if (f->ft_obj == obj && f->ft_amap == amap &&
+ f->ft_off == off) {
f->ft_refcnt++;
break;
}
@@ -177,6 +187,7 @@ futex_get(uint32_t *uaddr, int flags)
f = pool_get(&ftpool, PR_WAITOK);
TAILQ_INIT(&f->ft_threads);
f->ft_obj = obj;
+ f->ft_amap = amap;
f->ft_off = off;
f->ft_refcnt = 1;
LIST_INSERT_HEAD(ftlist, f, ft_list);