diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-04-04 18:44:23 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-04-04 18:44:23 +0000 |
commit | 7a286765e65095119b1fc6a4becd1c2f7ca506f4 (patch) | |
tree | 403714d720b32db73fcc87c8e01235a424c1b144 | |
parent | 7adf2d4b3ebcb53ca3991d7a205a49ac48c6b3a3 (diff) |
Make sure that identifycpu() is run only once; fixes occasional
hangs on resume. Discussed with and ok kettenis, haesbaert
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 41 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 3 |
2 files changed, 26 insertions, 18 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index b81deb3ebf5..1221401cf42 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.46 2012/03/27 02:23:04 haesbaert Exp $ */ +/* $OpenBSD: cpu.c,v 1.47 2012/04/04 18:44:22 mikeb Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -445,16 +445,17 @@ cpu_start_secondary(struct cpu_info *ci) #endif } - atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFY); + if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) { + atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFY); - /* - * wait for it to identify - */ - for (i = 100000; (ci->ci_flags & CPUF_IDENTIFY) && i > 0; i--) - delay(10); - - if (ci->ci_flags & CPUF_IDENTIFY) - printf("%s: failed to identify\n", ci->ci_dev->dv_xname); + /* wait for it to identify */ + for (i = 100000; (ci->ci_flags & CPUF_IDENTIFY) && i > 0; i--) + delay(10); + + if (ci->ci_flags & CPUF_IDENTIFY) + printf("%s: failed to identify\n", + ci->ci_dev->dv_xname); + } CPU_START_CLEANUP(ci); } @@ -504,15 +505,21 @@ cpu_hatch(void *v) lapic_enable(); lapic_startclock(); - /* We need to wait until we can identify, otherwise dmesg output - * will be messy. */ - while ((ci->ci_flags & CPUF_IDENTIFY) == 0) - delay(10); + if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) { + /* + * We need to wait until we can identify, otherwise dmesg + * output will be messy. + */ + while ((ci->ci_flags & CPUF_IDENTIFY) == 0) + delay(10); - identifycpu(ci); + identifycpu(ci); - /* Signal we're done */ - atomic_clearbits_int(&ci->ci_flags, CPUF_IDENTIFY); + /* Signal we're done */ + atomic_clearbits_int(&ci->ci_flags, CPUF_IDENTIFY); + /* Prevent identifycpu() from running again */ + atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFIED); + } while ((ci->ci_flags & CPUF_GO) == 0) delay(10); diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index e3f5ff0dead..8b4e3dcb6e8 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.71 2012/03/27 02:23:04 haesbaert Exp $ */ +/* $OpenBSD: cpu.h,v 1.72 2012/04/04 18:44:22 mikeb Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -136,6 +136,7 @@ struct cpu_info { #define CPUF_PRIMARY 0x0008 /* CPU is active primary processor */ #define CPUF_IDENTIFY 0x0010 /* CPU may now identify */ +#define CPUF_IDENTIFIED 0x0020 /* CPU has been identified */ #define CPUF_PRESENT 0x1000 /* CPU is present */ #define CPUF_RUNNING 0x2000 /* CPU is running */ |