Print the last non-wakeup interrupt received during suspend. Note that
authorkettenis <kettenis@openbsd.org>
Tue, 25 Jun 2024 12:02:48 +0000 (12:02 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 25 Jun 2024 12:02:48 +0000 (12:02 +0000)
this may print an (MSI) interrupt that sneaks in just before we actually
enter the idle loop on the primary CPU.  While such an interrupt shouldn't
happen, they won't prevent the machine from reaching a low power idle state.
So at this point these non-wakeup interrupts only need to be investigated
when the primary CPU gets woken up repeatedly.

ok mglocker@, deraadt@

sys/arch/amd64/amd64/intr.c

index 88c65f2..44fad99 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: intr.c,v 1.60 2024/06/15 18:01:44 kettenis Exp $      */
+/*     $OpenBSD: intr.c,v 1.61 2024/06/25 12:02:48 kettenis Exp $      */
 /*     $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $    */
 
 /*
@@ -74,6 +74,7 @@ struct pic softintr_pic = {
 };
 
 int intr_suspended;
+struct intrhand *intr_nowake;
 
 /*
  * Fill in default interrupt table (in case of spurious interrupt
@@ -537,8 +538,10 @@ intr_handler(struct intrframe *frame, struct intrhand *ih)
         * We may not be able to mask MSIs, so block non-wakeup
         * interrupts while we're suspended.
         */
-       if (intr_suspended && (ih->ih_flags & IPL_WAKEUP) == 0)
+       if (intr_suspended && (ih->ih_flags & IPL_WAKEUP) == 0) {
+               intr_nowake = ih;
                return 0;
+       }
 
 #ifdef MULTIPROCESSOR
        if (ih->ih_flags & IPL_MPSAFE)
@@ -749,6 +752,13 @@ intr_disable_wakeup(void)
                if (pic->pic_hwunmask)
                        pic->pic_hwunmask(pic, pin);
        }
+
+       if (intr_nowake) {
+               printf("last non-wakeup interrupt: irq%d/%s\n",
+                   *(int *)intr_nowake->ih_count.ec_data,
+                   intr_nowake->ih_count.ec_name);
+               intr_nowake = NULL;
+       }
 }
 
 #endif