From c00e3ee5947324bc41b88ad8619d4c3992b60d9b Mon Sep 17 00:00:00 2001 From: Taylor R Campbell <riastradh@NetBSD.org> Date: Thu, 10 Mar 2022 00:55:42 +0000 Subject: [PATCH 1/2] kern: Use atomic_store_release/atomic_load_consume for pid_table. This is read without the lock, so ordering is required. --- sys/kern/kern_proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 90f383ef0fd8..dc5a3d7400fc 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -695,7 +695,7 @@ proc_find_lwp(proc_t *p, pid_t pid) * memory barrier for dependent loads on alpha. */ s = pserialize_read_enter(); - pt = &pid_table[pid & pid_tbl_mask]; + pt = &atomic_load_consume(&pid_table)[pid & pid_tbl_mask]; slot = atomic_load_consume(&pt->pt_slot); if (__predict_false(!PT_IS_LWP(slot))) { pserialize_read_exit(s); @@ -753,7 +753,7 @@ proc_find_lwp_unlocked(proc_t *p, pid_t pid) * care to read the slot atomically and only once. This issues a * memory barrier for dependent loads on alpha. */ - pt = &pid_table[pid & pid_tbl_mask]; + pt = &atomic_load_consume(&pid_table)[pid & pid_tbl_mask]; slot = atomic_load_consume(&pt->pt_slot); if (__predict_false(!PT_IS_LWP(slot))) { return NULL; @@ -1003,7 +1003,7 @@ expand_pid_table(void) /* Save old table size and switch tables */ tsz = pt_size * sizeof(struct pid_table); n_pt = pid_table; - pid_table = new_pt; + atomic_store_release(&pid_table, new_pt); pid_tbl_mask = new_pt_mask; /* From 0975b0fcc8a998909ef7b89e1119a7ddbd742a9e Mon Sep 17 00:00:00 2001 From: Taylor R Campbell <riastradh@NetBSD.org> Date: Thu, 10 Mar 2022 00:57:02 +0000 Subject: [PATCH 2/2] kern: Use atomic_store_release for pid_table::pt_slot. Not clear the necessary membar was issued in proc_alloc_pid. Fewer store-release once at boot, not a big deal. --- sys/kern/kern_proc.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index dc5a3d7400fc..fdbb3338cff8 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1083,7 +1083,7 @@ proc_alloc_pid_slot(struct proc *p, uintptr_t slot) p != &proc0)) { KASSERT(PT_IS_PROC(slot)); pt = &pid_table[1]; - pt->pt_slot = slot; + atomic_store_release(&pt->pt_slot, slot); return 1; } pt = &pid_table[next_free_pt]; @@ -1107,7 +1107,7 @@ proc_alloc_pid_slot(struct proc *p, uintptr_t slot) KASSERT(pid <= FUTEX_TID_MASK); /* Grab table slot */ - pt->pt_slot = slot; + atomic_store_release(&pt->pt_slot, slot); KASSERT(pt->pt_pid == 0); pt->pt_pid = pid; @@ -1143,15 +1143,6 @@ proc_alloc_lwpid(struct proc *p, struct lwp *l) KASSERT(l->l_proc == p); KASSERT(l->l_stat == LSIDL); - /* - * For unlocked lookup in proc_find_lwp(), make sure l->l_proc - * is globally visible before the LWP becomes visible via the - * pid_table. - */ -#ifndef __HAVE_ATOMIC_AS_MEMBAR - membar_producer(); -#endif - /* * If the slot for p->p_pid currently points to the proc, * then we should usurp this ID for the LWP. This happens @@ -1166,7 +1157,7 @@ proc_alloc_lwpid(struct proc *p, struct lwp *l) if (PT_IS_PROC(pt->pt_slot)) { KASSERT(PT_GET_PROC(pt->pt_slot) == p); l->l_lid = pid; - pt->pt_slot = PT_SET_LWP(l); + atomic_store_release(&pt->pt_slot, PT_SET_LWP(l)); } else { /* Need to allocate a new slot. */ pid = proc_alloc_pid_slot(p, PT_SET_LWP(l));