From c2deaa264eb22f64bada8c0985204587d2f0da7c Mon Sep 17 00:00:00 2001 From: ad Date: Thu, 24 Apr 2008 13:56:30 +0000 Subject: [PATCH] xc_broadcast: don't try to run cross calls on CPUs that are not yet running. --- sys/kern/kern_idle.c | 9 +++++++-- sys/kern/subr_autoconf.c | 9 ++++++--- sys/kern/subr_xcall.c | 8 +++++--- sys/sys/sched.h | 3 ++- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_idle.c b/sys/kern/kern_idle.c index 9b9b12e122fc..0aecf7ce2366 100644 --- a/sys/kern/kern_idle.c +++ b/sys/kern/kern_idle.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_idle.c,v 1.13 2008/04/04 17:21:22 ad Exp $ */ +/* $NetBSD: kern_idle.c,v 1.14 2008/04/24 13:56:30 ad Exp $ */ /*- * Copyright (c)2002, 2006, 2007 YAMAMOTO Takashi, @@ -28,7 +28,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: kern_idle.c,v 1.13 2008/04/04 17:21:22 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_idle.c,v 1.14 2008/04/24 13:56:30 ad Exp $"); #include #include @@ -55,12 +55,17 @@ idle_loop(void *dummy) struct lwp *l = curlwp; unsigned mask = (1 << cpu_index(ci)); bool set = false; + int s; /* Update start time for this thread. */ lwp_lock(l); binuptime(&l->l_stime); lwp_unlock(l); + s = splsched(); + ci->ci_schedstate.spc_flags |= SPCF_RUNNING; + splx(s); + KERNEL_UNLOCK_ALL(l, NULL); l->l_stat = LSONPROC; while (1 /* CONSTCOND */) { diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c index 6c6fa6b89e1a..6165605b1b10 100644 --- a/sys/kern/subr_autoconf.c +++ b/sys/kern/subr_autoconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.145 2008/04/22 11:45:28 ad Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.146 2008/04/24 13:56:30 ad Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.145 2008/04/22 11:45:28 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.146 2008/04/24 13:56:30 ad Exp $"); #include "opt_multiprocessor.h" #include "opt_ddb.h" @@ -406,7 +406,7 @@ void configure(void) { extern void ssp_init(void); - int i; + int i, s; /* Initialize data structures. */ config_init(); @@ -440,6 +440,9 @@ configure(void) initclocks(); cold = 0; /* clocks are running, we're warm now! */ + s = splsched(); + curcpu()->ci_schedstate.spc_flags |= SPCF_RUNNING; + splx(s); /* Boot the secondary processors. */ mp_online = true; diff --git a/sys/kern/subr_xcall.c b/sys/kern/subr_xcall.c index c3311724b0df..5d656cb7f67d 100644 --- a/sys/kern/subr_xcall.c +++ b/sys/kern/subr_xcall.c @@ -1,7 +1,7 @@ -/* $NetBSD: subr_xcall.c,v 1.7 2008/04/14 00:18:43 ad Exp $ */ +/* $NetBSD: subr_xcall.c,v 1.8 2008/04/24 13:56:30 ad Exp $ */ /*- - * Copyright (c) 2007 The NetBSD Foundation, Inc. + * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -81,7 +81,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.7 2008/04/14 00:18:43 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_xcall.c,v 1.8 2008/04/24 13:56:30 ad Exp $"); #include #include @@ -191,6 +191,8 @@ xc_lowpri(u_int flags, xcfunc_t func, void *arg1, void *arg2, if (ci == NULL) { xc_broadcast_ev.ev_count++; for (CPU_INFO_FOREACH(cii, ci)) { + if ((ci->ci_schedstate.spc_flags & SPCF_RUNNING) == 0) + continue; xc_headp += 1; ci->ci_data.cpu_xcall_pending = true; cv_signal(&ci->ci_data.cpu_xcall); diff --git a/sys/sys/sched.h b/sys/sys/sched.h index df9a415b8bb7..e6403881ac9d 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $NetBSD: sched.h,v 1.51 2008/04/12 17:02:09 ad Exp $ */ +/* $NetBSD: sched.h,v 1.52 2008/04/24 13:56:30 ad Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -177,6 +177,7 @@ struct schedstate_percpu { #define SPCF_SEENRR 0x0001 /* process has seen roundrobin() */ #define SPCF_SHOULDYIELD 0x0002 /* process should yield the CPU */ #define SPCF_OFFLINE 0x0004 /* CPU marked offline */ +#define SPCF_RUNNING 0x0008 /* CPU is running */ #define SPCF_SWITCHCLEAR (SPCF_SEENRR|SPCF_SHOULDYIELD)