Index: arch/macppc/dev/macintr.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/dev/macintr.c,v retrieving revision 1.50 diff -u -p -r1.50 macintr.c --- arch/macppc/dev/macintr.c 4 Jan 2015 13:01:42 -0000 1.50 +++ arch/macppc/dev/macintr.c 5 Feb 2015 10:21:45 -0000 @@ -167,16 +167,10 @@ macintr_spllower(int newcpl) void macintr_splx(int newcpl) { - struct cpu_info *ci = curcpu(); - int intr, s; + int intr; intr = ppc_intr_disable(); macintr_setipl(newcpl); - if ((newcpl < IPL_SOFTTTY && ci->ci_ipending & ppc_smask[newcpl])) { - s = splsofttty(); - dosoftint(newcpl); - macintr_setipl(s); /* no-overhead splx */ - } ppc_intr_enable(intr); } Index: arch/macppc/dev/openpic.c =================================================================== RCS file: /cvs/src/sys/arch/macppc/dev/openpic.c,v retrieving revision 1.76 diff -u -p -r1.76 openpic.c --- arch/macppc/dev/openpic.c 4 Jan 2015 13:01:42 -0000 1.76 +++ arch/macppc/dev/openpic.c 5 Feb 2015 10:21:45 -0000 @@ -275,16 +275,10 @@ openpic_spllower(int newcpl) void openpic_splx(int newcpl) { - struct cpu_info *ci = curcpu(); - int intr, s; + int intr; intr = ppc_intr_disable(); openpic_setipl(newcpl); - if (newcpl < IPL_SOFTTTY && (ci->ci_ipending & ppc_smask[newcpl])) { - s = splsofttty(); - dosoftint(newcpl); - openpic_setipl(s); /* no-overhead splx */ - } ppc_intr_enable(intr); } Index: arch/powerpc/include/intr.h =================================================================== RCS file: /cvs/src/sys/arch/powerpc/include/intr.h,v retrieving revision 1.50 diff -u -p -r1.50 intr.h --- arch/powerpc/include/intr.h 4 Jan 2015 13:01:42 -0000 1.50 +++ arch/powerpc/include/intr.h 5 Feb 2015 10:21:45 -0000 @@ -130,38 +130,12 @@ void splassert_check(int, const char *); #define SI_NQUEUES 3 -#include -#include - -struct soft_intrhand { - TAILQ_ENTRY(soft_intrhand) sih_list; - void (*sih_func)(void *); - void *sih_arg; - struct soft_intrq *sih_siq; - int sih_pending; -}; - -struct soft_intrq { - TAILQ_HEAD(, soft_intrhand) siq_list; - int siq_si; - struct mutex siq_mtx; -}; - - +void softintr_init(void); +void *softintr_establish(int, void (*)(void *), void *); void softintr_disestablish(void *); void softintr_dispatch(int); -void *softintr_establish(int, void (*)(void *), void *); -void softintr_init(void); - void softintr_schedule(void *); -void dosoftint(int); - -#define set_sint(p) atomic_setbits_int(&curcpu()->ci_ipending, p) -#define setsoftclock() set_sint(SI_TO_IRQBIT(SI_SOFTCLOCK)) -#define setsoftnet() set_sint(SI_TO_IRQBIT(SI_SOFTNET)) -#define setsofttty() set_sint(SI_TO_IRQBIT(SI_SOFTTTY)) - #define splhigh() splraise(IPL_HIGH) #define spl0() spllower(IPL_NONE) Index: arch/powerpc/powerpc/intr.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc/powerpc/intr.c,v retrieving revision 1.8 diff -u -p -r1.8 intr.c --- arch/powerpc/powerpc/intr.c 4 Jan 2015 13:01:42 -0000 1.8 +++ arch/powerpc/powerpc/intr.c 5 Feb 2015 10:21:45 -0000 @@ -119,9 +119,6 @@ ppc_dflt_splx(int newcpl) struct cpu_info *ci = curcpu(); ci->ci_cpl = newcpl; - - if (ci->ci_ipending & ppc_smask[newcpl]) - dosoftint(newcpl); } struct ppc_intr_func ppc_intr_func = Index: arch/powerpc/powerpc/softintr.c =================================================================== RCS file: /cvs/src/sys/arch/powerpc/powerpc/softintr.c,v retrieving revision 1.7 diff -u -p -r1.7 softintr.c --- arch/powerpc/powerpc/softintr.c 4 Jan 2015 13:01:42 -0000 1.7 +++ arch/powerpc/powerpc/softintr.c 5 Feb 2015 10:21:45 -0000 @@ -38,16 +38,19 @@ #include #include -#include +#include #include -#include #include -struct soft_intrq soft_intrq[SI_NQUEUES]; +struct taskq *soft_intrq[SI_NQUEUES]; -struct soft_intrhand *softnet_intrhand; +struct si_init_task { + struct task t; + int ipl; +}; +void softintr_init_task(void *); /* * Initialize the software interrupt system. @@ -55,47 +58,46 @@ struct soft_intrhand *softnet_intrhand; void softintr_init(void) { - struct soft_intrq *siq; + static const struct { + const char *name; + int ipl; + } info[SI_NQUEUES] = { + { "softclock", IPL_SOFTCLOCK }, + { "softnet", IPL_SOFTNET }, + { "softtty", IPL_SOFTTTY } + }; + + struct taskq *siq; + struct si_init_task *ini; int i; for (i = 0; i < SI_NQUEUES; i++) { - siq = &soft_intrq[i]; - TAILQ_INIT(&siq->siq_list); - siq->siq_si = i; - mtx_init(&siq->siq_mtx, IPL_HIGH); + siq = taskq_create(info[i].name, 1, IPL_HIGH); + KASSERT(siq != NULL); + soft_intrq[i] = siq; + + /* try and make splasserts ok */ + ini = malloc(sizeof(*ini), M_TEMP, M_WAITOK); + task_set(&ini->t, softintr_init_task, ini); + ini->ipl = info[i].ipl; + task_add(siq, &ini->t); } } -/* - * Process pending software interrupts on the specified queue. - * - * NOTE: We must already be at the correct interrupt priority level. - */ void -softintr_dispatch(int si) +softintr_init_task(void *xini) { - struct soft_intrq *siq = &soft_intrq[si]; - struct soft_intrhand *sih; - - for (;;) { - mtx_enter(&siq->siq_mtx); - sih = TAILQ_FIRST(&siq->siq_list); - if (sih == NULL) { - mtx_leave(&siq->siq_mtx); - break; - } - - TAILQ_REMOVE(&siq->siq_list, sih, sih_list); - sih->sih_pending = 0; + struct si_init_task *ini = xini; - uvmexp.softs++; - - mtx_leave(&siq->siq_mtx); - - (*sih->sih_func)(sih->sih_arg); - } + splraise(ini->ipl); + free(ini, M_TEMP, sizeof(*ini)); } +struct soft_intrhand { + struct task sih_task; + struct taskq *sih_queue; +}; + /* * Register a software interrupt handler. */ @@ -128,10 +130,8 @@ softintr_establish(int ipl, void (*func) sih = malloc(sizeof(*sih), M_DEVBUF, M_NOWAIT); if (__predict_true(sih != NULL)) { - sih->sih_func = func; - sih->sih_arg = arg; - sih->sih_siq = &soft_intrq[si]; - sih->sih_pending = 0; + task_set(&sih->sih_task, func, arg); + sih->sih_queue = soft_intrq[si]; } return (sih); } @@ -143,16 +143,9 @@ void softintr_disestablish(void *arg) { struct soft_intrhand *sih = arg; - struct soft_intrq *siq = sih->sih_siq; - - mtx_enter(&siq->siq_mtx); - if (sih->sih_pending) { - TAILQ_REMOVE(&siq->siq_list, sih, sih_list); - sih->sih_pending = 0; - } - mtx_leave(&siq->siq_mtx); - free(sih, M_DEVBUF, 0); + task_del(sih->sih_queue, &sih->sih_task); + free(sih, M_DEVBUF, sizeof(*sih)); } /* @@ -162,37 +155,6 @@ void softintr_schedule(void *arg) { struct soft_intrhand *sih = (struct soft_intrhand *)arg; - struct soft_intrq *siq = sih->sih_siq; - struct cpu_info *ci = curcpu(); - - mtx_enter(&siq->siq_mtx); - if (sih->sih_pending == 0) { - TAILQ_INSERT_TAIL(&siq->siq_list, sih, sih_list); - sih->sih_pending = 1; - atomic_setbits_int(&ci->ci_ipending, SI_TO_IRQBIT(siq->siq_si)); - } - mtx_leave(&siq->siq_mtx); -} - -void -dosoftint(int pcpl) -{ - struct cpu_info *ci = curcpu(); - int sir, q, mask; - - ppc_intr_enable(1); - KERNEL_LOCK(); - - while ((sir = (ci->ci_ipending & ppc_smask[pcpl])) != 0) { - atomic_clearbits_int(&ci->ci_ipending, sir); - - for (q = SI_NQUEUES - 1; q >= 0; q--) { - mask = SI_TO_IRQBIT(q); - if (sir & mask) - softintr_dispatch(q); - } - } - KERNEL_UNLOCK(); - (void)ppc_intr_disable(); + task_add(sih->sih_queue, &sih->sih_task); } Index: kern/kern_task.c =================================================================== RCS file: /cvs/src/sys/kern/kern_task.c,v retrieving revision 1.13 diff -u -p -r1.13 kern_task.c --- kern/kern_task.c 27 Jan 2015 03:17:36 -0000 1.13 +++ kern/kern_task.c 5 Feb 2015 10:21:45 -0000 @@ -190,6 +190,9 @@ task_add(struct taskq *tq, struct task * { int rv = 0; + if (ISSET(w->t_flags, TASK_ONQUEUE)) + return (0); + mtx_enter(&tq->tq_mtx); if (!ISSET(w->t_flags, TASK_ONQUEUE)) { rv = 1;