diff options
author | jkim <jkim@FreeBSD.org> | 2009-03-17 00:48:11 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2009-03-17 00:48:11 +0000 |
commit | 3eda4741daa9db3ec9fa89000bfbf69dd182e01e (patch) | |
tree | c75b77d8208c29993db8a02658e1f33e9e5339b8 /sys/kern | |
parent | 4e75ea04f545069138b54e1fee5b5c1236ba5b68 (diff) | |
download | FreeBSD-src-3eda4741daa9db3ec9fa89000bfbf69dd182e01e.zip FreeBSD-src-3eda4741daa9db3ec9fa89000bfbf69dd182e01e.tar.gz |
Initial suspend/resume support for amd64.
This code is heavily inspired by Takanori Watanabe's experimental SMP patch
for i386 and large portion was shamelessly cut and pasted from Peter Wemm's
AP boot code.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_smp.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index e807e48..1a3a6fa 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -262,6 +262,54 @@ stop_cpus(cpumask_t map) return 1; } +#if defined(__amd64__) +/* + * When called the executing CPU will send an IPI to all other CPUs + * requesting that they halt execution. + * + * Usually (but not necessarily) called with 'other_cpus' as its arg. + * + * - Signals all CPUs in map to suspend. + * - Waits for each to suspend. + * + * Returns: + * -1: error + * 0: NA + * 1: ok + * + * XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs + * from executing at same time. + */ +int +suspend_cpus(cpumask_t map) +{ + int i; + + if (!smp_started) + return (0); + + CTR1(KTR_SMP, "suspend_cpus(%x)", map); + + /* send the suspend IPI to all CPUs in map */ + ipi_selected(map, IPI_SUSPEND); + + i = 0; + while ((stopped_cpus & map) != map) { + /* spin */ + cpu_spinwait(); + i++; +#ifdef DIAGNOSTIC + if (i == 100000) { + printf("timeout suspending cpus\n"); + break; + } +#endif + } + + return (1); +} +#endif + /* * Called by a CPU to restart stopped CPUs. * |