diff options
author | avg <avg@FreeBSD.org> | 2013-02-02 12:02:42 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2013-02-02 12:02:42 +0000 |
commit | 09a43450b8e300637ed1d8238be2e28d3a727adb (patch) | |
tree | 9901a738d6efc2c6aa1dd55e1cd0595b82b88cb6 /sys/x86 | |
parent | 8e238c660c83a64a3ceb5bd22afe0ee62ec3cba4 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/x86')
-rw-r--r-- | sys/x86/x86/intr_machdep.c | 12 | ||||
-rw-r--r-- | sys/x86/x86/local_apic.c | 11 |
2 files changed, 15 insertions, 8 deletions
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"); |