summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2010-04-06 20:33:29 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2010-04-06 20:33:29 +0000
commit9f642be1ec713ecb21b38fceb1bd23a1b41e9c65 (patch)
tree798ca8c3a3cfd5a33d8a42deb5828b08e8b4d90e /sys
parentd7f3a349bc1c450a2007eee8acdfdb56e0b3f99a (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.c53
-rw-r--r--sys/kern/kern_xxx.c27
-rw-r--r--sys/sys/sched.h8
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);