svn commit: r271000 - head/sys/kern
Bryan Drewery
bdrewery at FreeBSD.org
Wed Sep 3 15:06:11 UTC 2014
On 9/3/2014 3:18 AM, Konstantin Belousov wrote:
> Author: kib
> Date: Wed Sep 3 08:18:07 2014
> New Revision: 271000
> URL: http://svnweb.freebsd.org/changeset/base/271000
>
> Log:
> Right now, thread_single(SINGLE_EXIT) returns after the p_numthreads
> reaches 1. The p_numthreads counter is decremented in thread_exit() by
> a call to thread_unlink(). This means that the exiting threads may
> still execute on other CPUs when thread_single(SINGLE_EXIT) returns.
> As result, vmspace could be destroyed while paging structures are
> still used on other CPUs by exiting threads.
>
> Delay the return from thread_single(SINGLE_EXIT) until all threads are
> really destroyed by thread_stash() after the last switch out. The
> p_exitthreads counter already provides the required mechanism, move
> the wait from the thread_wait() (which is called from wait(2) code)
> into thread_single().
>
> Reported by: many (as "panic: pmap active <addr>")
> Reviewed by: alc, jhb
> Tested by: pho
> Sponsored by: The FreeBSD Foundation
> MFC after: 1 week
>
> Modified:
> head/sys/kern/kern_thread.c
>
> Modified: head/sys/kern/kern_thread.c
> ==============================================================================
> --- head/sys/kern/kern_thread.c Wed Sep 3 08:14:07 2014 (r270999)
> +++ head/sys/kern/kern_thread.c Wed Sep 3 08:18:07 2014 (r271000)
> @@ -432,6 +432,7 @@ thread_exit(void)
> */
> if (p->p_flag & P_HADTHREADS) {
> if (p->p_numthreads > 1) {
> + atomic_add_int(&td->td_proc->p_exitthreads, 1);
> thread_unlink(td);
> td2 = FIRST_THREAD_IN_PROC(p);
> sched_exit_thread(td2, td);
> @@ -452,7 +453,6 @@ thread_exit(void)
> }
> }
>
> - atomic_add_int(&td->td_proc->p_exitthreads, 1);
> PCPU_SET(deadthread, td);
> } else {
> /*
> @@ -507,14 +507,12 @@ thread_wait(struct proc *p)
> struct thread *td;
>
> mtx_assert(&Giant, MA_NOTOWNED);
> - KASSERT((p->p_numthreads == 1), ("Multiple threads in wait1()"));
> + KASSERT((p->p_numthreads == 1), ("multiple threads in thread_wait()"));
> + KASSERT((p->p_exitthreads == 0), ("p_exitthreads leaking"));
> td = FIRST_THREAD_IN_PROC(p);
> /* Lock the last thread so we spin until it exits cpu_throw(). */
> thread_lock(td);
> thread_unlock(td);
> - /* Wait for any remaining threads to exit cpu_throw(). */
> - while (p->p_exitthreads)
> - sched_relinquish(curthread);
> lock_profile_thread_exit(td);
> cpuset_rel(td->td_cpuset);
> td->td_cpuset = NULL;
> @@ -722,6 +720,17 @@ stopme:
> p->p_singlethread = NULL;
> p->p_flag &= ~(P_STOPPED_SINGLE | P_SINGLE_EXIT);
> thread_unthread(td);
> +
> + /*
> + * Wait for any remaining threads to exit cpu_throw().
> + */
> + while (p->p_exitthreads != 0) {
> + PROC_SUNLOCK(p);
> + PROC_UNLOCK(p);
> + sched_relinquish(td);
> + PROC_LOCK(p);
> + PROC_SLOCK(p);
> + }
> }
> PROC_SUNLOCK(p);
> return (0);
>
Thanks!
--
Regards,
Bryan Drewery
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/svn-src-head/attachments/20140903/a96e7d81/attachment.sig>
More information about the svn-src-head
mailing list