diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-04-06 20:33:29 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-04-06 20:33:29 +0000 |
commit | 9f642be1ec713ecb21b38fceb1bd23a1b41e9c65 (patch) | |
tree | 798ca8c3a3cfd5a33d8a42deb5828b08e8b4d90e /sys | |
parent | d7f3a349bc1c450a2007eee8acdfdb56e0b3f99a (diff) |
Implement functions to take away the secondary CPUs from the scheduler and
give them back again, effectively stopping and starting these CPUs. Use
the stop function in sys_reboot().
ok marco@, deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_sched.c | 53 | ||||
-rw-r--r-- | sys/kern/kern_xxx.c | 27 | ||||
-rw-r--r-- | sys/sys/sched.h | 8 |
3 files changed, 62 insertions, 26 deletions
diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 7625440b7ee..1b58a16a367 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.17 2010/01/09 02:44:17 kettenis Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.18 2010/04/06 20:33:28 kettenis Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski <art@openbsd.org> * @@ -32,7 +32,6 @@ void sched_kthreads_create(void *); -void sched_idle(void *); int sched_proc_to_cpu_cost(struct cpu_info *ci, struct proc *p); struct proc *sched_steal_proc(struct cpu_info *); @@ -546,6 +545,56 @@ sched_peg_curproc(struct cpu_info *ci) SCHED_UNLOCK(s); } +#ifdef MULTIPROCESSOR + +void +sched_start_secondary_cpus(void) +{ + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + + CPU_INFO_FOREACH(cii, ci) { + struct schedstate_percpu *spc = &ci->ci_schedstate; + + if (CPU_IS_PRIMARY(ci)) + continue; + atomic_clearbits_int(&spc->spc_schedflags, + SPCF_SHOULDHALT | SPCF_HALTED); + } +} + +void +sched_stop_secondary_cpus(void) +{ + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + + /* + * Make sure we stop the secondary CPUs. + */ + CPU_INFO_FOREACH(cii, ci) { + struct schedstate_percpu *spc = &ci->ci_schedstate; + + if (CPU_IS_PRIMARY(ci)) + continue; + atomic_setbits_int(&spc->spc_schedflags, SPCF_SHOULDHALT); + } + CPU_INFO_FOREACH(cii, ci) { + struct schedstate_percpu *spc = &ci->ci_schedstate; + struct sleep_state sls; + + if (CPU_IS_PRIMARY(ci)) + continue; + while ((spc->spc_schedflags & SPCF_HALTED) == 0) { + sleep_setup(&sls, spc, PZERO, "schedstate"); + sleep_finish(&sls, + (spc->spc_schedflags & SPCF_HALTED) == 0); + } + } +} + +#endif + /* * Functions to manipulate cpu sets. */ diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index 359c97541f2..abe7c4be0df 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_xxx.c,v 1.15 2010/01/09 02:44:17 kettenis Exp $ */ +/* $OpenBSD: kern_xxx.c,v 1.16 2010/04/06 20:33:28 kettenis Exp $ */ /* $NetBSD: kern_xxx.c,v 1.32 1996/04/22 01:38:41 christos Exp $ */ /* @@ -68,28 +68,9 @@ sys_reboot(struct proc *p, void *v, register_t *retval) } } - /* - * Make sure we stop the secondary CPUs. - */ - CPU_INFO_FOREACH(cii, ci) { - struct schedstate_percpu *spc = &ci->ci_schedstate; - - if (CPU_IS_PRIMARY(ci)) - continue; - atomic_setbits_int(&spc->spc_schedflags, SPCF_SHOULDHALT); - } - CPU_INFO_FOREACH(cii, ci) { - struct schedstate_percpu *spc = &ci->ci_schedstate; - struct sleep_state sls; - - if (CPU_IS_PRIMARY(ci)) - continue; - while ((spc->spc_schedflags & SPCF_HALTED) == 0) { - sleep_setup(&sls, spc, PZERO, "schedstate"); - sleep_finish(&sls, - (spc->spc_schedflags & SPCF_HALTED) == 0); - } - } +#ifdef MULTIPROCESSOR + sched_stop_secondary_cpus(); +#endif if_downall(); diff --git a/sys/sys/sched.h b/sys/sys/sched.h index 9304a631628..9f2a9d3e1be 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.25 2010/01/09 02:44:17 kettenis Exp $ */ +/* $OpenBSD: sched.h,v 1.26 2010/04/06 20:33:28 kettenis Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -138,6 +138,7 @@ struct cpu_info; void roundrobin(struct cpu_info *); void sched_init_cpu(struct cpu_info *); +void sched_idle(void *); void sched_exit(struct proc *); void mi_switch(void); void cpu_switchto(struct proc *, struct proc *); @@ -149,6 +150,11 @@ void cpu_idle_cycle(void); void cpu_idle_leave(void); void sched_peg_curproc(struct cpu_info *ci); +#ifdef MULTIPROCESSOR +void sched_start_secondary_cpus(void); +void sched_stop_secondary_cpus(void); +#endif + #define curcpu_is_idle() (curcpu()->ci_schedstate.spc_whichqs == 0) void sched_init_runqueues(void); |