Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Apr 2011 14:58:35 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Ryan Stone <rysto32@gmail.com>
Cc:        freebsd-current@freebsd.org, Ed Maste <emaste@freebsd.org>
Subject:   Re: sched_4bsd startup crash trying to run a bound thread on an AP that hasn't started
Message-ID:  <201104251458.35718.jhb@freebsd.org>
In-Reply-To: <BANLkTin9MgwyZtyiLWJsHbFxv0ihicbiEg@mail.gmail.com>
References:  <BANLkTinSyDaY-06N95n8c1NxOSdEnb5FkQ@mail.gmail.com> <201104061429.50185.jhb@freebsd.org> <BANLkTin9MgwyZtyiLWJsHbFxv0ihicbiEg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday, April 20, 2011 6:02:42 pm Ryan Stone wrote:
> On Wed, Apr 6, 2011 at 2:29 PM, John Baldwin <jhb@freebsd.org> wrote:
> > I guess one other option would be something like this:
> >
> >                if (smp_started && (td->td_pinned != 0 || td->td_flags & TDF_BOUND ||
> >                    ts->ts_flags & TSF_AFFINITY)) {
> >                        if (td->td_pinned != 0)
> >                                cpu = td->td_lastcpu;
> >                        else if (td->td_flags & TDF_BOUND) {
> >                                /* Find CPU from bound runq. */
> >                                KASSERT(...);
> >                                cpu = ts->ts_runq - &runq_pcpu[0];
> >                        } else
> >                                /* Find a valid CPU for our cpuset. */
> >                                cpu = sched_pickcpu(td);
> >                        ts->ts_runq = &runq_pcpu[cpu];
> >                        single_cpu = 1;
> >                        CTR3(KTR_RUNQ, ...);
> >                } else {
> >                        /* Global runq case. */
> >                }
> >
> > This also avoids duplicating some common code to all the single_cpu cases.
> >
> > --
> > John Baldwin
> >
> 
> I went with this option.  Does this look right?

Yes, I would perhaps tweak the comment to reflect the full if statement
though.  Maybe something like:

/*
 * If SMP is started and the thread is pinned or otherwise limited to
 * a specific set of CPUs, queue the thread to a per-CPU run queue.
 * Otherwise, queue the thread to the global run queue.
 */

> 
> Index: sys/kern/sched_4bsd.c
> ===================================================================
> --- sys/kern/sched_4bsd.c       (revision 220603)
> +++ sys/kern/sched_4bsd.c       (working copy)
> @@ -1246,30 +1246,28 @@
>         }
>         TD_SET_RUNQ(td);
> 
> -       if (td->td_pinned != 0) {
> -               cpu = td->td_lastcpu;
> +       /*
> +        * If SMP is not started, don't obey any requested CPU pinning as that
> +        * CPU has either not yet started or it is curcpu.  Trying to run a
> +        * thread on a CPU that has not yet started will panic the system.
> +        */
> +       if (smp_started && (td->td_pinned != 0 || td->td_flags & TDF_BOUND ||
> +           ts->ts_flags & TSF_AFFINITY)) {
> +               if (td->td_pinned != 0)
> +                       cpu = td->td_lastcpu;
> +               else if (td->td_flags & TDF_BOUND) {
> +                       /* Find CPU from bound runq. */
> +                       KASSERT(SKE_RUNQ_PCPU(ts),
> +                           ("sched_add: bound td_sched not on cpu runq"));
> +                       cpu = ts->ts_runq - &runq_pcpu[0];
> +               } else
> +                       /* Find a valid CPU for our cpuset */
> +                       cpu = sched_pickcpu(td);
>                 ts->ts_runq = &runq_pcpu[cpu];
>                 single_cpu = 1;
>                 CTR3(KTR_RUNQ,
>                     "sched_add: Put td_sched:%p(td:%p) on cpu%d runq", ts, td,
>                     cpu);
> -       } else if (td->td_flags & TDF_BOUND) {
> -               /* Find CPU from bound runq. */
> -               KASSERT(SKE_RUNQ_PCPU(ts),
> -                   ("sched_add: bound td_sched not on cpu runq"));
> -               cpu = ts->ts_runq - &runq_pcpu[0];
> -               single_cpu = 1;
> -               CTR3(KTR_RUNQ,
> -                   "sched_add: Put td_sched:%p(td:%p) on cpu%d runq", ts, td,
> -                   cpu);
> -       } else if (ts->ts_flags & TSF_AFFINITY) {
> -               /* Find a valid CPU for our cpuset */
> -               cpu = sched_pickcpu(td);
> -               ts->ts_runq = &runq_pcpu[cpu];
> -               single_cpu = 1;
> -               CTR3(KTR_RUNQ,
> -                   "sched_add: Put td_sched:%p(td:%p) on cpu%d runq", ts, td,
> -                   cpu);
>         } else {
>                 CTR2(KTR_RUNQ,
>                     "sched_add: adding td_sched:%p (td:%p) to gbl runq", ts,
> 

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104251458.35718.jhb>