path: root/sys/sys
diff options
authorJamie Gritton <jamie@FreeBSD.org>2021-01-20 23:08:27 +0000
committerJamie Gritton <jamie@FreeBSD.org>2021-01-20 23:08:27 +0000
commit6754ae2572eb20dbc23d2452b5e8fe4e07125f93 (patch)
tree070f256c6ded85f48cb153fbcbf4dcfd1bf10e85 /sys/sys
parente3dd8ed77b4e7d8fda12ec80b91d89e8460b64f8 (diff)
jail: Use refcount(9) for prison references.
Use refcount(9) for both pr_ref and pr_uref in struct prison. This allows prisons to held and freed without requiring the prison mutex. An exception to this is that dropping the last reference will still lock the prison, to keep the guarantee that a locked prison remains valid and alive (provided it was at the time it was locked). Among other things, this honors the promise made in a comment in crcopy(9), that it will not block, which hasn't been true for two decades.
Diffstat (limited to 'sys/sys')
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/sys/jail.h b/sys/sys/jail.h
index 67ef9347d093..2d1a26787b99 100644
--- a/sys/sys/jail.h
+++ b/sys/sys/jail.h
@@ -150,17 +150,18 @@ struct prison_racct;
* Lock key:
* (a) allprison_lock
+ * (c) set only during creation before the structure is shared, no mutex
+ * required to read
* (m) locked by pr_mtx
* (p) locked by pr_mtx, and also at least shared allprison_lock required
* to update
- * (c) set only during creation before the structure is shared, no mutex
- * required to read
+ * (r) atomic via refcount(9), pr_mtx required to decrement to zero
struct prison {
TAILQ_ENTRY(prison) pr_list; /* (a) all prisons */
int pr_id; /* (c) prison id */
- int pr_ref; /* (m) refcount */
- int pr_uref; /* (m) user (alive) refcount */
+ volatile u_int pr_ref; /* (r) refcount */
+ volatile u_int pr_uref; /* (r) user (alive) refcount */
unsigned pr_flags; /* (p) PR_* flags */
LIST_HEAD(, prison) pr_children; /* (a) list of child jails */
LIST_ENTRY(prison) pr_sibling; /* (a) next in parent's list */