summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_prot.c
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2018-06-21 13:58:21 +0000
committervisa <visa@openbsd.org>2018-06-21 13:58:21 +0000
commit0ff991d2469a5e6b2ec82348ccae67e31455ec55 (patch)
treea2c3a76c752e360bc0c5b8e1bd312d11b5d02f3a /sys/kern/kern_prot.c
parentShuffle fields around to eliminate blanks spots resulting from (diff)
downloadwireguard-openbsd-0ff991d2469a5e6b2ec82348ccae67e31455ec55.tar.xz
wireguard-openbsd-0ff991d2469a5e6b2ec82348ccae67e31455ec55.zip
Use atomic operations for updating cred structure reference counts
to make crfree() and crhold() MP-safe. Make crhold() a proper function. Put the definition into file kern_prot.c to constrain the need of the <sys/atomic.h> header. While there, adjust the IPL of ucred_pool to avoid lock order problems with the kernel lock (pointed out by kettenis@). OK mpi@
Diffstat (limited to 'sys/kern/kern_prot.c')
-rw-r--r--sys/kern/kern_prot.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index ec7ac4d4f32..5622d3b3c94 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_prot.c,v 1.73 2018/02/20 12:38:58 mpi Exp $ */
+/* $OpenBSD: kern_prot.c,v 1.74 2018/06/21 13:58:21 visa Exp $ */
/* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */
/*
@@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/acct.h>
+#include <sys/atomic.h>
#include <sys/systm.h>
#include <sys/ucred.h>
#include <sys/proc.h>
@@ -948,6 +949,17 @@ crget(void)
}
/*
+ * Increment the reference count of a cred structure.
+ * Return the passed structure.
+ */
+struct ucred *
+crhold(struct ucred *cr)
+{
+ atomic_inc_int(&cr->cr_ref);
+ return (cr);
+}
+
+/*
* Free a cred structure.
* Throws away space when ref count gets to 0.
*/
@@ -955,7 +967,7 @@ void
crfree(struct ucred *cr)
{
- if (--cr->cr_ref == 0)
+ if (atomic_dec_int_nv(&cr->cr_ref) == 0)
pool_put(&ucred_pool, cr);
}