diff options
author | 2009-11-25 11:01:14 +0000 | |
---|---|---|
committer | 2009-11-25 11:01:14 +0000 | |
commit | d746c22dec89954371da372e701c622c09423b88 (patch) | |
tree | 19c61c25114ba54b2ff7fae0d76edeaf708fcbaf | |
parent | Italian translations (diff) | |
download | wireguard-openbsd-d746c22dec89954371da372e701c622c09423b88.tar.xz wireguard-openbsd-d746c22dec89954371da372e701c622c09423b88.zip |
Add a mechanism to stop the scheduler from scheduling processes on a
particular CPU such that it just sits and spins in the idle loop, effectively
halting that CPU.
ok deraadt@, miod@
-rw-r--r-- | sys/kern/kern_sched.c | 14 | ||||
-rw-r--r-- | sys/kern/kern_xxx.c | 21 | ||||
-rw-r--r-- | sys/sys/sched.h | 4 |
3 files changed, 35 insertions, 4 deletions
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 15d57cf037c..6066c6a92f4 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.14 2009/10/05 17:43:08 deraadt Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.15 2009/11/25 11:01:14 kettenis Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org> * @@ -146,6 +146,11 @@ sched_idle(void *v) splassert(IPL_NONE); + if (spc->spc_schedflags & SPCF_SHOULDHALT) { + spc->spc_schedflags |= SPCF_HALTED; + wakeup(spc); + } + cpuset_add(&sched_idle_cpus, ci); cpu_idle_enter(); while (spc->spc_whichqs == 0) @@ -246,6 +251,13 @@ sched_chooseproc(void) SCHED_ASSERT_LOCKED(); + if (spc->spc_schedflags & SPCF_SHOULDHALT) { + p = spc->spc_idleproc; + KASSERT(p); + p->p_stat = SRUN; + return (p); + } + again: if (spc->spc_whichqs) { queue = ffs(spc->spc_whichqs) - 1; diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index 5beade18f06..a842462a218 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_xxx.c,v 1.12 2009/08/10 11:22:10 deraadt Exp $ */ +/* $OpenBSD: kern_xxx.c,v 1.13 2009/11/25 11:01:14 kettenis Exp $ */ /* $NetBSD: kern_xxx.c,v 1.32 1996/04/22 01:38:41 christos Exp $ */ /* @@ -53,7 +53,7 @@ sys_reboot(struct proc *p, void *v, register_t *retval) } */ *uap = v; CPU_INFO_ITERATOR cii; struct cpu_info *ci; - int error; + int error, s; if ((error = suser(p, 0)) != 0) return (error); @@ -68,6 +68,23 @@ sys_reboot(struct proc *p, void *v, register_t *retval) } } + /* + * Make sure we stop the secondary CPUs. + */ + s = splstatclock(); + CPU_INFO_FOREACH(cii, ci) { + if (CPU_IS_PRIMARY(ci)) + continue; + ci->ci_schedstate.spc_schedflags |= SPCF_SHOULDHALT; + } + CPU_INFO_FOREACH(cii, ci) { + if (CPU_IS_PRIMARY(ci)) + continue; + while ((ci->ci_schedstate.spc_schedflags & SPCF_HALTED) == 0) + tsleep(&ci->ci_schedstate, PZERO, "schedstate", 0); + } + splx(s); + if_downall(); boot(SCARG(uap, opt)); diff --git a/sys/sys/sched.h b/sys/sys/sched.h index 8211961b815..4220960e480 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.22 2009/04/14 09:13:25 art Exp $ */ +/* $OpenBSD: sched.h,v 1.23 2009/11/25 11:01:14 kettenis Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -122,6 +122,8 @@ struct schedstate_percpu { #define SPCF_SEENRR 0x0001 /* process has seen roundrobin() */ #define SPCF_SHOULDYIELD 0x0002 /* process should yield the CPU */ #define SPCF_SWITCHCLEAR (SPCF_SEENRR|SPCF_SHOULDYIELD) +#define SPCF_SHOULDHALT 0x0004 /* CPU should be vacated */ +#define SPCF_HALTED 0x0008 /* CPU has been halted */ #define SCHED_PPQ (128 / SCHED_NQS) /* priorities per queue */ #define NICE_WEIGHT 2 /* priorities per nice level */ |