Module Name: src Committed By: jmcneill Date: Mon Feb 17 11:14:49 UTC 2025
Modified Files: src/sys/arch/powerpc/pic: intr.c picvar.h Log Message: powerpc: Don't enable interrupts before calling cascaded intr handler. Before calling a normal interrupt handler, the pic code adjusts cpl and enables interrupts. Don't do this with interrupt sources that feed cascaded pics as the resulting handler will do it anyway, and it can result in multiple interrupts firing on the parent pic just to service a single interrupt on the child. To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.37 src/sys/arch/powerpc/pic/intr.c cvs rdiff -u -r1.13 -r1.14 src/sys/arch/powerpc/pic/picvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/powerpc/pic/intr.c diff -u src/sys/arch/powerpc/pic/intr.c:1.36 src/sys/arch/powerpc/pic/intr.c:1.37 --- src/sys/arch/powerpc/pic/intr.c:1.36 Sun Feb 16 09:55:00 2025 +++ src/sys/arch/powerpc/pic/intr.c Mon Feb 17 11:14:49 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: intr.c,v 1.36 2025/02/16 09:55:00 jmcneill Exp $ */ +/* $NetBSD: intr.c,v 1.37 2025/02/17 11:14:49 jmcneill Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -29,7 +29,7 @@ #define __INTR_PRIVATE #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.36 2025/02/16 09:55:00 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.37 2025/02/17 11:14:49 jmcneill Exp $"); #ifdef _KERNEL_OPT #include "opt_interrupt.h" @@ -180,10 +180,12 @@ intr_establish_xname(int hwirq, int type hwirq, type); struct intr_source * const is = &intrsources[virq]; + const bool cascaded = ih_fun == pic_handle_intr; switch (is->is_type) { case IST_NONE: is->is_type = type; + is->is_cascaded = cascaded; break; case IST_EDGE_FALLING: case IST_EDGE_RISING: @@ -193,10 +195,15 @@ intr_establish_xname(int hwirq, int type break; /* FALLTHROUGH */ case IST_PULSE: - if (type != IST_NONE) + if (type != IST_NONE) { panic("intr_establish: can't share %s with %s", intr_typename(is->is_type), intr_typename(type)); + } + if (cascaded != is->is_cascaded) { + panic("intr_establish: can't share cascaded with " + "non-cascaded interrupt"); + } break; } if (is->is_hand == NULL) { @@ -519,11 +526,15 @@ again: struct intr_source * const is = &intrsources[virq]; struct pic_ops * const pic = is->is_pic; - splraise(is->is_ipl); - mtmsr(emsr); + if (!is->is_cascaded) { + splraise(is->is_ipl); + mtmsr(emsr); + } intr_deliver(is, virq); - mtmsr(dmsr); - ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ + if (!is->is_cascaded) { + mtmsr(dmsr); + ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */ + } pic->pic_reenable_irq(pic, is->is_hwirq - pic->pic_intrbase, is->is_type); @@ -587,11 +598,15 @@ pic_handle_intr(void *cookie) ci->ci_ipending &= ~v_imen; ci->ci_idepth++; - splraise(is->is_ipl); - mtmsr(msr | PSL_EE); + if (!is->is_cascaded) { + splraise(is->is_ipl); + mtmsr(msr | PSL_EE); + } intr_deliver(is, virq); - mtmsr(msr & ~PSL_EE); - ci->ci_cpl = pcpl; + if (!is->is_cascaded) { + mtmsr(msr & ~PSL_EE); + ci->ci_cpl = pcpl; + } ci->ci_data.cpu_nintr++; ci->ci_idepth--; Index: src/sys/arch/powerpc/pic/picvar.h diff -u src/sys/arch/powerpc/pic/picvar.h:1.13 src/sys/arch/powerpc/pic/picvar.h:1.14 --- src/sys/arch/powerpc/pic/picvar.h:1.13 Mon Mar 22 01:36:10 2021 +++ src/sys/arch/powerpc/pic/picvar.h Mon Feb 17 11:14:49 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: picvar.h,v 1.13 2021/03/22 01:36:10 rin Exp $ */ +/* $NetBSD: picvar.h,v 1.14 2025/02/17 11:14:49 jmcneill Exp $ */ /*- * Copyright (c) 2007 Michael Lorenz @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: picvar.h,v 1.13 2021/03/22 01:36:10 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: picvar.h,v 1.14 2025/02/17 11:14:49 jmcneill Exp $"); #ifndef PIC_VAR_H #define PIC_VAR_H @@ -61,6 +61,7 @@ struct intr_source { imask_t is_mask; struct intrhand *is_hand; struct pic_ops *is_pic; + bool is_cascaded; struct evcnt is_ev; char is_evname[16]; char is_intrid[INTRIDBUF];