Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Apr 2004 18:02:00 -0400 (EDT)
From:      Daniel Eischen <eischen@vigrid.com>
To:        John Baldwin <jhb@FreeBSD.org>
Cc:        davidxu@FreeBSD.org
Subject:   Re: kse_release and kse_wakeup problem (fwd)
Message-ID:  <Pine.GSO.4.10.10404221759560.15790-100000@pcnet5.pcnet.com>
In-Reply-To: <200404220954.00469.jhb@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Sorry, I should have included threads@.

On Thu, 22 Apr 2004, John Baldwin wrote:

> On Thursday 22 April 2004 09:01 am, Daniel Eischen wrote:
> > What do you guys think of this patch?
> 
> I think that the thread code should check for the upcall case the same way 

The thread code where?  Everywhere msleep() is called?

> that we check for signals by calliing cursig() in sleepq_catch_signals(), 
> that is:
> 
>         /* Mark thread as being in an interruptible sleep. */
>         mtx_lock_spin(&sched_lock);
>         MPASS(TD_ON_SLEEPQ(td));
>         td->td_flags |= TDF_SINTR;
>         mtx_unlock_spin(&sched_lock);
>         sleepq_release(wchan);
> 
>         /* See if there are any pending signals for this thread. */
>         PROC_LOCK(p);
>         mtx_lock(&p->p_sigacts->ps_mtx);
>         sig = cursig(td);
>         mtx_unlock(&p->p_sigacts->ps_mtx);
>         if (sig == 0 && thread_suspend_check(1))
>                 sig = SIGSTOP;
>         PROC_UNLOCK(p);
> 
>         /*
>          * If there were pending signals and this thread is still on
>          * the sleep queue, remove it from the sleep queue.
>          */
> 
> The thread_suspend_check() code should also be checking for the UPCALL case 
> and as well.  Maybe something like:
> 
> 	if (sig == 0 && thread_suspend_check(1))
> 		sig == SIGSTOP;
> 	if (sig == 0 && thread_upcall_check())
> 		doing_upcall = 1;
> 
> and then dequeue if we are doing an upcall just like we do if there is already 
> a signal.  This mirrors the way we handle signals since UPCALLs are a kind of 
> special cased signal.  The patch below has incorrect locking (td_flags could 
> get trashed) by the way.
> 
> > ---------- Forwarded message ----------
> > Date: Thu, 22 Apr 2004 15:27:05 +0900
> > From: Kazuaki Oda <kaakun@highway.ne.jp>
> > To: threads@freebsd.org
> > Subject: kse_release and kse_wakeup problem
> >
> > Hi,
> >
> > I think, after switching to use new sleep queue interface, there is a
> > problem when using scope system threads on MP machine.
> > This problem occurs when one CPU is executing kse_release and another
> > is kse_wakeup.
> >
> >
> > There is a scenario (thread A and B is on the same process):
> >
> > CPU0: thread A aquires PROC_LOCK in kse_release (kern_thread.c 621)
> > CPU0: thread A releases PROC_LOCK in msleep (kern_synch.c 209)
> > CPU1: thread B aquires PROC_LOCK in kse_wakeup (kern_thread.c 667)
> > CPU1: thread B looks up kse_upcall (kern_thread.c 669-687)
> > CPU1: thread B gets kse_upcall owner and this is thread A (kern_thread.c
> > 689) CPU1: thread B sets KUF_DOUPCALL flag (kern_thread.c 697)
> >       because thread A is not on sleep queue yet,
> >       sleepq_abort (kern_thread.c 695) is not executed.
> > CPU1: thread B releases PROC_LOCK (kern_thread.c 700)
> > CPU0: thread A puts himself on sleep queue (kern_synch.c 221)
> > CPU0: thread A sets TDF_SINTR flag (subr_sleepqueue.c 310)
> > CPU0: thread A sleeps and context switch occurs...
> >
> >
> > I think, thread B should call sleepq_abort and thread A should do
> > upcall as soon as possible.
> > The following patch is for thread A to release PROC_LOCK after putting
> > himself on sleep queue and setting TDF_SINTR flag.
> > I don't think this patch is so good (obviously setting TDF_SINTR here is
> > not good), but enough for test.
> >
> > And, after patching, MySQL does not hang up on heavy load on my machine
> > (P4 2.40GHz, HTT enabled).
> >
> >
> > --- kern_synch.c.orig   Thu Apr 22 14:00:40 2004
> > +++ kern_synch.c        Thu Apr 22 12:20:06 2004
> > @@ -203,11 +203,6 @@
> >             td, p->p_pid, p->p_comm, wmesg, ident);
> >
> >         DROP_GIANT();
> > -       if (mtx != NULL) {
> > -               mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED);
> > -               WITNESS_SAVE(&mtx->mtx_object, mtx);
> > -               mtx_unlock(mtx);
> > -       }
> >
> >         /*
> >          * We put ourselves on the sleep queue and start our timeout
> > @@ -219,6 +214,13 @@
> >          * return from cursig().
> >          */
> >         sleepq_add(sq, ident, mtx, wmesg, 0);
> > +       if (catch)
> > +               td->td_flags |= TDF_SINTR;
> > +       if (mtx != NULL) {
> > +               mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED);
> > +               WITNESS_SAVE(&mtx->mtx_object, mtx);
> > +               mtx_unlock(mtx);
> > +       }
> >         if (timo)
> >                 sleepq_set_timeout(ident, timo);
> >         if (catch) {
> 
> -- 
> John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
> "Power Users Use the Power to Serve"  =  http://www.FreeBSD.org
> 

-- 
"Some folks are into open source, but me, I'm into open bar."
                                          -- Spencer F. Katt



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10404221759560.15790-100000>