diff options
-rw-r--r-- | sys/arch/arm/arm/softintr.c | 16 | ||||
-rw-r--r-- | sys/arch/arm/include/softintr.h | 15 | ||||
-rw-r--r-- | sys/arch/sh/include/intr.h | 9 | ||||
-rw-r--r-- | sys/arch/sh/sh/interrupt.c | 33 |
4 files changed, 36 insertions, 37 deletions
diff --git a/sys/arch/arm/arm/softintr.c b/sys/arch/arm/arm/softintr.c index 96480df841e..b7d8202e30d 100644 --- a/sys/arch/arm/arm/softintr.c +++ b/sys/arch/arm/arm/softintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softintr.c,v 1.5 2009/04/08 21:19:30 kettenis Exp $ */ +/* $OpenBSD: softintr.c,v 1.6 2009/04/19 18:54:06 oga Exp $ */ /* $NetBSD: softintr.c,v 1.2 2003/07/15 00:24:39 lukem Exp $ */ /* @@ -67,6 +67,7 @@ softintr_init(void) for (i = 0; i < SI_NQUEUES; i++) { siq = &soft_intrq[i]; TAILQ_INIT(&siq->siq_list); + mtx_init(&siq->siq_mtx, IPL_HIGH); siq->siq_si = i; } @@ -89,13 +90,12 @@ softintr_dispatch(int si) { struct soft_intrq *siq = &soft_intrq[si]; struct soft_intrhand *sih; - int oldirqstate; for (;;) { - oldirqstate = disable_interrupts(I32_bit); + mtx_enter(&siq->siq_mtx); sih = TAILQ_FIRST(&siq->siq_list); if (sih == NULL) { - restore_interrupts(oldirqstate); + mtx_leave(&siq->siq_mtx); break; } @@ -103,8 +103,7 @@ softintr_dispatch(int si) sih->sih_pending = 0; uvmexp.softs++; - - restore_interrupts(oldirqstate); + mtx_leave(&siq->siq_mtx); (*sih->sih_func)(sih->sih_arg); } @@ -163,14 +162,13 @@ softintr_disestablish(void *arg) { struct soft_intrhand *sih = arg; struct soft_intrq *siq = sih->sih_siq; - int oldirqstate; - oldirqstate = disable_interrupts(I32_bit); + mtx_enter(&siq->siq_mtx); if (sih->sih_pending) { TAILQ_REMOVE(&siq->siq_list, sih, sih_list); sih->sih_pending = 0; } - restore_interrupts(oldirqstate); + mtx_leave(&siq->siq_mtx); free(sih, M_DEVBUF); } diff --git a/sys/arch/arm/include/softintr.h b/sys/arch/arm/include/softintr.h index cc4065ba67c..8d3feb39fba 100644 --- a/sys/arch/arm/include/softintr.h +++ b/sys/arch/arm/include/softintr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: softintr.h,v 1.3 2009/04/08 21:19:30 kettenis Exp $ */ +/* $OpenBSD: softintr.h,v 1.4 2009/04/19 18:54:06 oga Exp $ */ /* $NetBSD: softintr.h,v 1.1 2002/01/29 22:54:14 thorpej Exp $ */ /* @@ -41,6 +41,8 @@ #ifdef _KERNEL +#include <sys/mutex.h> + /* * Generic software interrupt support for all ARM platforms. * @@ -64,8 +66,10 @@ struct soft_intrhand { }; struct soft_intrq { - TAILQ_HEAD(, soft_intrhand) siq_list; - int siq_si; + TAILQ_HEAD(, soft_intrhand) + siq_list; + int siq_si; + struct mutex siq_mtx; }; void *softintr_establish(int, void (*)(void *), void *); @@ -77,15 +81,14 @@ void softintr_dispatch(int); do { \ struct soft_intrhand *__sih = (arg); \ struct soft_intrq *__siq = __sih->sih_siq; \ - int __s; \ \ - __s = splhigh(); \ + mtx_enter(&__siq->siq_mtx); \ if (__sih->sih_pending == 0) { \ TAILQ_INSERT_TAIL(&__siq->siq_list, __sih, sih_list); \ __sih->sih_pending = 1; \ _setsoftintr(__siq->siq_si); \ } \ - splx(__s); \ + mtx_leave(&__siq->siq_mtx); \ } while (/*CONSTCOND*/0) /* XXX For legacy software interrupts. */ diff --git a/sys/arch/sh/include/intr.h b/sys/arch/sh/include/intr.h index ce274d1245f..886494c6dd7 100644 --- a/sys/arch/sh/include/intr.h +++ b/sys/arch/sh/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.6 2009/03/25 21:40:56 miod Exp $ */ +/* $OpenBSD: intr.h,v 1.7 2009/04/19 18:54:06 oga Exp $ */ /* $NetBSD: intr.h,v 1.22 2006/01/24 23:51:42 uwe Exp $ */ /*- @@ -35,6 +35,7 @@ #include <sys/device.h> #include <sys/evcount.h> #include <sys/lock.h> +#include <sys/mutex.h> #include <sys/queue.h> #include <sh/psl.h> @@ -101,8 +102,10 @@ struct sh_soft_intrhand { }; struct sh_soft_intr { - TAILQ_HEAD(, sh_soft_intrhand) softintr_q; - unsigned long softintr_ipl; + TAILQ_HEAD(, sh_soft_intrhand) + softintr_q; + unsigned long softintr_ipl; + struct mutex softintr_lock; }; void softintr_disestablish(void *); diff --git a/sys/arch/sh/sh/interrupt.c b/sys/arch/sh/sh/interrupt.c index b46588cf123..17ff868bb6c 100644 --- a/sys/arch/sh/sh/interrupt.c +++ b/sys/arch/sh/sh/interrupt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: interrupt.c,v 1.9 2009/03/25 21:41:00 miod Exp $ */ +/* $OpenBSD: interrupt.c,v 1.10 2009/04/19 18:54:06 oga Exp $ */ /* $NetBSD: interrupt.c,v 1.18 2006/01/25 00:02:57 uwe Exp $ */ /*- @@ -585,7 +585,7 @@ softintr_init(void) for (i = 0; i < _IPL_NSOFT; i++) { asi = &sh_soft_intrs[i]; TAILQ_INIT(&asi->softintr_q); - + mtx_init(&asi->softintr_lock, IPL_HIGH); asi->softintr_ipl = IPL_SOFT + i; } @@ -605,24 +605,24 @@ softintr_dispatch(int ipl) { struct sh_soft_intr *asi; struct sh_soft_intrhand *sih; - int s; - - s = _cpu_intr_suspend(); asi = &sh_soft_intrs[ipl - IPL_SOFT]; - while ((sih = TAILQ_FIRST(&asi->softintr_q)) != NULL) { + for (;;) { + mtx_enter(&asi->softintr_lock); + sih = TAILQ_FIRST(&asi->softintr_q); + if (sih == NULL) { + mtx_leave(&asi->softintr_lock); + break; + } TAILQ_REMOVE(&asi->softintr_q, sih, sih_q); sih->sih_pending = 0; uvmexp.softs++; + mtx_leave(&asi->softintr_lock); - _cpu_intr_resume(s); (*sih->sih_fn)(sih->sih_arg); - s = _cpu_intr_suspend(); } - - _cpu_intr_resume(s); } void @@ -640,7 +640,6 @@ softintr_establish(int ipl, void (*func)(void *), void *arg) { struct sh_soft_intr *asi; struct sh_soft_intrhand *sih; - int s; if (__predict_false(ipl >= (IPL_SOFT + _IPL_NSOFT) || ipl < IPL_SOFT)) @@ -648,7 +647,6 @@ softintr_establish(int ipl, void (*func)(void *), void *arg) sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT); - s = _cpu_intr_suspend(); asi = &sh_soft_intrs[ipl - IPL_SOFT]; if (__predict_true(sih != NULL)) { sih->sih_intrhead = asi; @@ -656,7 +654,6 @@ softintr_establish(int ipl, void (*func)(void *), void *arg) sih->sih_arg = arg; sih->sih_pending = 0; } - _cpu_intr_resume(s); return (sih); } @@ -667,14 +664,13 @@ softintr_disestablish(void *arg) { struct sh_soft_intrhand *sih = arg; struct sh_soft_intr *asi = sih->sih_intrhead; - int s; - s = _cpu_intr_suspend(); + mtx_enter(&asi->softintr_lock); if (sih->sih_pending) { TAILQ_REMOVE(&asi->softintr_q, sih, sih_q); sih->sih_pending = 0; } - _cpu_intr_resume(s); + mtx_leave(&asi->softintr_lock); free(sih, M_DEVBUF); } @@ -684,15 +680,14 @@ void softintr_schedule(void *arg) { struct sh_soft_intrhand *sih = arg; struct sh_soft_intr *si = sih->sih_intrhead; - int s; - s = _cpu_intr_suspend(); + mtx_enter(&si->softintr_lock); if (sih->sih_pending == 0) { TAILQ_INSERT_TAIL(&si->softintr_q, sih, sih_q); sih->sih_pending = 1; setsoft(si->softintr_ipl); } - _cpu_intr_resume(s); + mtx_leave(&si->softintr_lock); } /* |