summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2012-04-04 18:44:23 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2012-04-04 18:44:23 +0000
commit7a286765e65095119b1fc6a4becd1c2f7ca506f4 (patch)
tree403714d720b32db73fcc87c8e01235a424c1b144
parent7adf2d4b3ebcb53ca3991d7a205a49ac48c6b3a3 (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.c41
-rw-r--r--sys/arch/amd64/include/cpu.h3
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 */