diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-01-04 13:01:43 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-01-04 13:01:43 +0000 |
commit | b5aa09b33d64540760172d36438ee5864c0b24f4 (patch) | |
tree | d4b642b74030caea41fe90cdecbd3e87b8104afb /sys/arch/socppc | |
parent | 11e22c6125c49fc01f5752389ca129e42973f458 (diff) |
Implement splassert(9) for powerpc.
This changes the logic to prevent a recursion when processing soft
interrupts. Previously a per-CPU flag was set before re-enabling
interrupts. Now the IPL level is raised to SOFTTTY which makes
splsoftassert() happy, greatly inspired by mips64.
As a side effect, the ppc_intr_{disable,enable}() dance is now done
only once instead of twice per splx(9).
While here, make use of dosoftint() instead of having 3 different
functions for dispatching soft interrupts.
Tested by deraadt@ on G4 smp and by myself G5 smp, G3, G4 and socppc.
No objection from the usual (and over busy) suspects.
Diffstat (limited to 'sys/arch/socppc')
-rw-r--r-- | sys/arch/socppc/dev/ipic.c | 21 | ||||
-rw-r--r-- | sys/arch/socppc/socppc/machdep.c | 39 |
2 files changed, 15 insertions, 45 deletions
diff --git a/sys/arch/socppc/dev/ipic.c b/sys/arch/socppc/dev/ipic.c index b7205e5c490..44b4d37f305 100644 --- a/sys/arch/socppc/dev/ipic.c +++ b/sys/arch/socppc/dev/ipic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipic.c,v 1.16 2014/02/08 10:58:17 kettenis Exp $ */ +/* $OpenBSD: ipic.c,v 1.17 2015/01/04 13:01:42 mpi Exp $ */ /* * Copyright (c) 2008 Mark Kettenis @@ -298,11 +298,11 @@ intr_establish(int ivec, int type, int level, */ s = ppc_intr_disable(); TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list); - ppc_intr_enable(s); /* Unmask the interrupt. */ if (sc) ipic_setipl(curcpu()->ci_cpl); + ppc_intr_enable(s); return (ih); } @@ -347,11 +347,14 @@ ipic_splraise(int newcpl) { struct cpu_info *ci = curcpu(); int ocpl = ci->ci_cpl; + int s; if (ocpl > newcpl) newcpl = ocpl; + s = ppc_intr_disable(); ipic_setipl(newcpl); + ppc_intr_enable(s); return (ocpl); } @@ -371,21 +374,26 @@ void ipic_splx(int newcpl) { struct cpu_info *ci = curcpu(); + int intr, s; + intr = ppc_intr_disable(); ipic_setipl(newcpl); - if (ci->ci_ipending & ppc_smask[newcpl]) - do_pending_int(); + if (newcpl < IPL_SOFTTTY && (ci->ci_ipending & ppc_smask[newcpl])) { + s = splsofttty(); + dosoftint(newcpl); + ipic_setipl(s); /* no-overhead splx */ + } + ppc_intr_enable(intr); } +/* Must be called with interrupt disable. */ void ipic_setipl(int ipl) { struct cpu_info *ci = curcpu(); struct ipic_softc *sc = ipic_sc; uint32_t mask; - int s; - s = ppc_intr_disable(); ci->ci_cpl = ipl; mask = sc->sc_simsr_h[IPL_HIGH] & ~sc->sc_simsr_h[ipl]; ipic_write(sc, IPIC_SIMSR_H, mask); @@ -393,5 +401,4 @@ ipic_setipl(int ipl) ipic_write(sc, IPIC_SIMSR_L, mask); mask = sc->sc_semsr[IPL_HIGH] & ~sc->sc_semsr[ipl]; ipic_write(sc, IPIC_SEMSR, mask); - ppc_intr_enable(s); } diff --git a/sys/arch/socppc/socppc/machdep.c b/sys/arch/socppc/socppc/machdep.c index 2edb7167d7e..2f9d5fc3d1c 100644 --- a/sys/arch/socppc/socppc/machdep.c +++ b/sys/arch/socppc/socppc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.60 2014/12/10 15:29:53 mikeb Exp $ */ +/* $OpenBSD: machdep.c,v 1.61 2015/01/04 13:01:42 mpi Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -1084,43 +1084,6 @@ haltsys: /* NOTREACHED */ } -void -do_pending_int(void) -{ - struct cpu_info *ci = curcpu(); - int pcpl = ci->ci_cpl; /* XXX */ - int s; - s = ppc_intr_disable(); - if (ci->ci_flags & CI_FLAGS_PROCESSING_SOFT) { - ppc_intr_enable(s); - return; - } - atomic_setbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT); - - do { - if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTCLOCK)) && - (pcpl < IPL_SOFTCLOCK)) { - ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTCLOCK); - softintr_dispatch(SI_SOFTCLOCK); - } - if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTNET)) && - (pcpl < IPL_SOFTNET)) { - ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTNET); - softintr_dispatch(SI_SOFTNET); - } - if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTTTY)) && - (pcpl < IPL_SOFTTTY)) { - ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTTTY); - softintr_dispatch(SI_SOFTTTY); - } - - } while (ci->ci_ipending & ppc_smask[pcpl]); - splx(pcpl); - ppc_intr_enable(s); - - atomic_clearbits_int(&ci->ci_flags, CI_FLAGS_PROCESSING_SOFT); -} - /* * Notify the current process (p) that it has a signal pending, * process as soon as possible. |