--- a/sys/platform/vkernel64/x86_64/trap.c +++ b/sys/platform/vkernel64/x86_64/trap.c @@ -87,6 +87,7 @@ #include #include +#include #include #include @@ -155,6 +156,9 @@ * signal handling, faults, AST traps, and anything else that enters the * kernel from userland and provides the kernel with a stable read-only * copy of the process ucred. + * + * To avoid races with another thread updating p_ucred we obtain p_spin. + * The other thread doing the update will obtain both p_token and p_spin. */ static __inline void userenter(struct thread *curtd, struct proc *curp) @@ -164,8 +168,10 @@ curtd->td_release = lwkt_passive_release; - if (curtd->td_ucred != curp->p_ucred) { + if (__predict_false(curtd->td_ucred != curp->p_ucred)) { + spin_lock(&curp->p_spin); ncred = crhold(curp->p_ucred); + spin_unlock(&curp->p_spin); ocred = curtd->td_ucred; curtd->td_ucred = ncred; if (ocred)