summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_thread.c
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2015-06-10 10:43:59 +0000
committermjg <mjg@FreeBSD.org>2015-06-10 10:43:59 +0000
commit67f2eebb44e1f27017750eddaf5a5ea513cb9c71 (patch)
tree4be753ea914cbf9f2ee65a2a1cc53e6989224d5d /sys/kern/kern_thread.c
parentab3ad78145346dc115fb372ccf5f9bf7731075c9 (diff)
downloadFreeBSD-src-67f2eebb44e1f27017750eddaf5a5ea513cb9c71.zip
FreeBSD-src-67f2eebb44e1f27017750eddaf5a5ea513cb9c71.tar.gz
Generalised support for copy-on-write structures shared by threads.
Thread credentials are maintained as follows: each thread has a pointer to creds and a reference on them. The pointer is compared with proc's creds on userspace<->kernel boundary and updated if needed. This patch introduces a counter which can be compared instead, so that more structures can use this scheme without adding more comparisons on the boundary.
Diffstat (limited to 'sys/kern/kern_thread.c')
-rw-r--r--sys/kern/kern_thread.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index dce760c..2e97553 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -327,8 +327,7 @@ thread_reap(void)
mtx_unlock_spin(&zombie_lock);
while (td_first) {
td_next = TAILQ_NEXT(td_first, td_slpq);
- if (td_first->td_ucred)
- crfree(td_first->td_ucred);
+ thread_cow_free(td_first);
thread_free(td_first);
td_first = td_next;
}
@@ -384,6 +383,44 @@ thread_free(struct thread *td)
uma_zfree(thread_zone, td);
}
+void
+thread_cow_get_proc(struct thread *newtd, struct proc *p)
+{
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ newtd->td_ucred = crhold(p->p_ucred);
+ newtd->td_cowgen = p->p_cowgen;
+}
+
+void
+thread_cow_get(struct thread *newtd, struct thread *td)
+{
+
+ newtd->td_ucred = crhold(td->td_ucred);
+ newtd->td_cowgen = td->td_cowgen;
+}
+
+void
+thread_cow_free(struct thread *td)
+{
+
+ if (td->td_ucred)
+ crfree(td->td_ucred);
+}
+
+void
+thread_cow_update(struct thread *td)
+{
+ struct proc *p;
+
+ p = td->td_proc;
+ PROC_LOCK(p);
+ if (td->td_ucred != p->p_ucred)
+ cred_update_thread(td);
+ td->td_cowgen = p->p_cowgen;
+ PROC_UNLOCK(p);
+}
+
/*
* Discard the current thread and exit from its context.
* Always called with scheduler locked.
@@ -521,7 +558,7 @@ thread_wait(struct proc *p)
cpuset_rel(td->td_cpuset);
td->td_cpuset = NULL;
cpu_thread_clean(td);
- crfree(td->td_ucred);
+ thread_cow_free(td);
thread_reap(); /* check for zombie threads etc. */
}
OpenPOWER on IntegriCloud