summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2013-02-02 12:02:42 +0000
committeravg <avg@FreeBSD.org>2013-02-02 12:02:42 +0000
commit09a43450b8e300637ed1d8238be2e28d3a727adb (patch)
tree9901a738d6efc2c6aa1dd55e1cd0595b82b88cb6
parent8e238c660c83a64a3ceb5bd22afe0ee62ec3cba4 (diff)
downloadFreeBSD-src-09a43450b8e300637ed1d8238be2e28d3a727adb.zip
FreeBSD-src-09a43450b8e300637ed1d8238be2e28d3a727adb.tar.gz
x86 suspend/resume: suspend pics and pseudo-pics in reverse order
- change 'pics' from STAILQ to TAILQ - ensure that Local APIC is always first in 'pics' Reviewed by: jhb Tested by: Sergey V. Dyatko <sergey.dyatko@gmail.com>, KAHO Toshikazu <kaho@elam.kais.kyoto-u.ac.jp> MFC after: 12 days
-rw-r--r--sys/amd64/include/intr_machdep.h2
-rw-r--r--sys/i386/include/intr_machdep.h2
-rw-r--r--sys/x86/x86/intr_machdep.c12
-rw-r--r--sys/x86/x86/local_apic.c11
4 files changed, 17 insertions, 10 deletions
diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h
index 700e35f..8671605 100644
--- a/sys/amd64/include/intr_machdep.h
+++ b/sys/amd64/include/intr_machdep.h
@@ -94,7 +94,7 @@ struct pic {
int (*pic_config_intr)(struct intsrc *, enum intr_trigger,
enum intr_polarity);
int (*pic_assign_cpu)(struct intsrc *, u_int apic_id);
- STAILQ_ENTRY(pic) pics;
+ TAILQ_ENTRY(pic) pics;
};
/* Flags for pic_disable_source() */
diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h
index 004ed52..b3dd122 100644
--- a/sys/i386/include/intr_machdep.h
+++ b/sys/i386/include/intr_machdep.h
@@ -94,7 +94,7 @@ struct pic {
int (*pic_config_intr)(struct intsrc *, enum intr_trigger,
enum intr_polarity);
int (*pic_assign_cpu)(struct intsrc *, u_int apic_id);
- STAILQ_ENTRY(pic) pics;
+ TAILQ_ENTRY(pic) pics;
};
/* Flags for pic_disable_source() */
diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c
index 31cc80b..e21635f 100644
--- a/sys/x86/x86/intr_machdep.c
+++ b/sys/x86/x86/intr_machdep.c
@@ -78,7 +78,7 @@ static int intrcnt_index;
static struct intsrc *interrupt_sources[NUM_IO_INTS];
static struct mtx intr_table_lock;
static struct mtx intrcnt_lock;
-static STAILQ_HEAD(, pic) pics;
+static TAILQ_HEAD(pics_head, pic) pics;
#ifdef SMP
static int assign_cpu;
@@ -102,7 +102,7 @@ intr_pic_registered(struct pic *pic)
{
struct pic *p;
- STAILQ_FOREACH(p, &pics, pics) {
+ TAILQ_FOREACH(p, &pics, pics) {
if (p == pic)
return (1);
}
@@ -124,7 +124,7 @@ intr_register_pic(struct pic *pic)
if (intr_pic_registered(pic))
error = EBUSY;
else {
- STAILQ_INSERT_TAIL(&pics, pic, pics);
+ TAILQ_INSERT_TAIL(&pics, pic, pics);
error = 0;
}
mtx_unlock(&intr_table_lock);
@@ -287,7 +287,7 @@ intr_resume(void)
atpic_reset();
#endif
mtx_lock(&intr_table_lock);
- STAILQ_FOREACH(pic, &pics, pics) {
+ TAILQ_FOREACH(pic, &pics, pics) {
if (pic->pic_resume != NULL)
pic->pic_resume(pic);
}
@@ -300,7 +300,7 @@ intr_suspend(void)
struct pic *pic;
mtx_lock(&intr_table_lock);
- STAILQ_FOREACH(pic, &pics, pics) {
+ TAILQ_FOREACH_REVERSE(pic, &pics, pics_head, pics) {
if (pic->pic_suspend != NULL)
pic->pic_suspend(pic);
}
@@ -381,7 +381,7 @@ intr_init(void *dummy __unused)
intrcnt_setname("???", 0);
intrcnt_index = 1;
- STAILQ_INIT(&pics);
+ TAILQ_INIT(&pics);
mtx_init(&intr_table_lock, "intr sources", NULL, MTX_DEF);
mtx_init(&intrcnt_lock, "intrcnt", NULL, MTX_SPIN);
}
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index fc85abf3..c60db22 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -1360,11 +1360,19 @@ apic_setup_io(void *dummy __unused)
if (best_enum == NULL)
return;
+
+ /*
+ * Local APIC must be registered before other PICs and pseudo PICs
+ * for proper suspend/resume order.
+ */
+#ifndef XEN
+ intr_register_pic(&lapic_pic);
+#endif
+
retval = best_enum->apic_setup_io();
if (retval != 0)
printf("%s: Failed to setup I/O APICs: returned %d\n",
best_enum->apic_name, retval);
-
#ifdef XEN
return;
#endif
@@ -1373,7 +1381,6 @@ apic_setup_io(void *dummy __unused)
* properly program the LINT pins.
*/
lapic_setup(1);
- intr_register_pic(&lapic_pic);
if (bootverbose)
lapic_dump("BSP");
OpenPOWER on IntegriCloud