Index: crypto/crypto.c =================================================================== RCS file: /cvs/src/sys/crypto/crypto.c,v retrieving revision 1.73 diff -u -p -r1.73 crypto.c --- crypto/crypto.c 27 Jan 2015 03:17:35 -0000 1.73 +++ crypto/crypto.c 8 Feb 2015 09:55:02 -0000 @@ -495,7 +495,7 @@ crypto_getreq(int num) void crypto_init(void) { - crypto_taskq = taskq_create("crypto", 1, IPL_VM); + crypto_taskq = taskq_create("crypto", 1, IPL_VM, 0); pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0, 0, "cryptop", NULL); Index: dev/softraid.c =================================================================== RCS file: /cvs/src/sys/dev/softraid.c,v retrieving revision 1.348 diff -u -p -r1.348 softraid.c --- dev/softraid.c 27 Jan 2015 03:17:35 -0000 1.348 +++ dev/softraid.c 8 Feb 2015 09:55:02 -0000 @@ -3297,7 +3297,7 @@ sr_ioctl_createraid(struct sr_softc *sc, sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, M_WAITOK | M_ZERO); sd->sd_sc = sc; SLIST_INIT(&sd->sd_meta_opt); - sd->sd_taskq = taskq_create("srdis", 1, IPL_BIO); + sd->sd_taskq = taskq_create("srdis", 1, IPL_BIO, 0); if (sd->sd_taskq == NULL) { sr_error(sc, "could not create discipline taskq"); goto unwind; Index: dev/ic/qla.c =================================================================== RCS file: /cvs/src/sys/dev/ic/qla.c,v retrieving revision 1.47 diff -u -p -r1.47 qla.c --- dev/ic/qla.c 27 Jan 2015 03:17:36 -0000 1.47 +++ dev/ic/qla.c 8 Feb 2015 09:55:02 -0000 @@ -648,7 +648,7 @@ qla_attach(struct qla_softc *sc) goto free_scratch; } - sc->sc_update_taskq = taskq_create(DEVNAME(sc), 1, IPL_BIO); + sc->sc_update_taskq = taskq_create(DEVNAME(sc), 1, IPL_BIO, 0); task_set(&sc->sc_update_task, qla_do_update, sc); /* wait a bit for link to come up so we can scan and attach devices */ Index: dev/pci/qle.c =================================================================== RCS file: /cvs/src/sys/dev/pci/qle.c,v retrieving revision 1.33 diff -u -p -r1.33 qle.c --- dev/pci/qle.c 27 Jan 2015 03:17:36 -0000 1.33 +++ dev/pci/qle.c 8 Feb 2015 09:55:02 -0000 @@ -625,7 +625,7 @@ qle_attach(struct device *parent, struct goto free_scratch; } - sc->sc_update_taskq = taskq_create(DEVNAME(sc), 1, IPL_BIO); + sc->sc_update_taskq = taskq_create(DEVNAME(sc), 1, IPL_BIO, 0); task_set(&sc->sc_update_task, qle_do_update, sc); /* wait a bit for link to come up so we can scan and attach devices */ Index: dev/pci/viomb.c =================================================================== RCS file: /cvs/src/sys/dev/pci/viomb.c,v retrieving revision 1.11 diff -u -p -r1.11 viomb.c --- dev/pci/viomb.c 27 Jan 2015 03:17:36 -0000 1.11 +++ dev/pci/viomb.c 8 Feb 2015 09:55:02 -0000 @@ -202,7 +202,7 @@ viomb_attach(struct device *parent, stru goto err_dmamap; } - sc->sc_taskq = taskq_create("viomb", 1, IPL_BIO); + sc->sc_taskq = taskq_create("viomb", 1, IPL_BIO, 0); if (sc->sc_taskq == NULL) goto err_dmamap; task_set(&sc->sc_task, viomb_worker, sc); Index: dev/pci/drm/i915/i915_drv.c =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v retrieving revision 1.70 diff -u -p -r1.70 i915_drv.c --- dev/pci/drm/i915/i915_drv.c 27 Jan 2015 03:17:36 -0000 1.70 +++ dev/pci/drm/i915/i915_drv.c 8 Feb 2015 09:55:02 -0000 @@ -940,7 +940,7 @@ inteldrm_attach(struct device *parent, s return; } - dev_priv->mm.retire_taskq = taskq_create("intelrel", 1, IPL_TTY); + dev_priv->mm.retire_taskq = taskq_create("intelrel", 1, IPL_TTY, 0); if (dev_priv->mm.retire_taskq == NULL) { printf("couldn't create taskq\n"); return; Index: dev/pci/drm/ttm/ttm_memory.c =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/ttm/ttm_memory.c,v retrieving revision 1.5 diff -u -p -r1.5 ttm_memory.c --- dev/pci/drm/ttm/ttm_memory.c 27 Jan 2015 03:17:36 -0000 1.5 +++ dev/pci/drm/ttm/ttm_memory.c 8 Feb 2015 09:55:02 -0000 @@ -336,7 +336,7 @@ int ttm_mem_global_init(struct ttm_mem_g #endif mtx_init(&glob->lock, IPL_TTY); - glob->swap_queue = taskq_create("ttm_swap", 1, IPL_TTY); + glob->swap_queue = taskq_create("ttm_swap", 1, IPL_TTY, 0); glob->task_queued = false; task_set(&glob->task, ttm_shrink_work, glob); Index: kern/kern_sensors.c =================================================================== RCS file: /cvs/src/sys/kern/kern_sensors.c,v retrieving revision 1.34 diff -u -p -r1.34 kern_sensors.c --- kern/kern_sensors.c 27 Jan 2015 03:17:36 -0000 1.34 +++ kern/kern_sensors.c 8 Feb 2015 09:55:02 -0000 @@ -193,7 +193,7 @@ sensor_task_register(void *arg, void (*f #endif if (sensors_taskq == NULL && - (sensors_taskq = taskq_create("sensors", 1, IPL_HIGH)) == NULL) + (sensors_taskq = taskq_create("sensors", 1, IPL_HIGH, 0)) == NULL) sensors_taskq = systq; st = malloc(sizeof(*st), M_DEVBUF, M_NOWAIT); Index: kern/kern_synch.c =================================================================== RCS file: /cvs/src/sys/kern/kern_synch.c,v retrieving revision 1.116 diff -u -p -r1.116 kern_synch.c --- kern/kern_synch.c 8 Jul 2014 17:19:25 -0000 1.116 +++ kern/kern_synch.c 8 Feb 2015 09:55:02 -0000 @@ -191,6 +191,8 @@ sleep_setup(struct sleep_state *sls, con struct proc *p = curproc; #ifdef DIAGNOSTIC + if (p->p_flag & P_CANTSLEEP) + panic("sleep: %s failed insomnia", p->p_comm); if (ident == NULL) panic("tsleep: no ident"); if (p->p_stat != SONPROC) 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 8 Feb 2015 09:55:02 -0000 @@ -33,7 +33,7 @@ struct taskq { } tq_state; unsigned int tq_running; unsigned int tq_nthreads; - unsigned int tq_unlocked; + unsigned int tq_flags; const char *tq_name; struct mutex tq_mtx; @@ -54,18 +54,23 @@ struct taskq taskq_sys_mp = { TQ_S_CREATED, 0, 1, - 1, + TASKQ_MPSAFE, "systqmp", MUTEX_INITIALIZER(IPL_HIGH), TAILQ_HEAD_INITIALIZER(taskq_sys_mp.tq_worklist) }; +typedef int (*sleepfn)(const volatile void *, struct mutex *, int, + const char *, int); + struct taskq *const systq = &taskq_sys; struct taskq *const systqmp = &taskq_sys_mp; void taskq_init(void); /* called in init_main.c */ void taskq_create_thread(void *); -int taskq_next_work(struct taskq *, struct task *); +int taskq_sleep(const volatile void *, struct mutex *, int, + const char *, int); +int taskq_next_work(struct taskq *, struct task *, sleepfn); void taskq_thread(void *); void @@ -76,7 +81,8 @@ taskq_init(void) } struct taskq * -taskq_create(const char *name, unsigned int nthreads, int ipl) +taskq_create(const char *name, unsigned int nthreads, int ipl, + unsigned int flags) { struct taskq *tq; @@ -88,12 +94,7 @@ taskq_create(const char *name, unsigned tq->tq_running = 0; tq->tq_nthreads = nthreads; tq->tq_name = name; - - if (ipl & IPL_MPSAFE) - tq->tq_unlocked = 1; - else - tq->tq_unlocked = 0; - ipl &= ~IPL_MPSAFE; + tq->tq_flags = flags; mtx_init(&tq->tq_mtx, ipl); TAILQ_INIT(&tq->tq_worklist); @@ -190,6 +191,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; @@ -209,6 +213,9 @@ task_del(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; @@ -221,7 +228,21 @@ task_del(struct taskq *tq, struct task * } int -taskq_next_work(struct taskq *tq, struct task *work) +taskq_sleep(const volatile void *ident, struct mutex *mtx, int priority, + const char *wmesg, int tmo) +{ + u_int *flags = &curproc->p_flag; + int rv; + + atomic_clearbits_int(flags, P_CANTSLEEP); + rv = msleep(ident, mtx, priority, wmesg, tmo); + atomic_setbits_int(flags, P_CANTSLEEP); + + return (tmo); +} + +int +taskq_next_work(struct taskq *tq, struct task *work, sleepfn tqsleep) { struct task *next; @@ -232,7 +253,7 @@ taskq_next_work(struct taskq *tq, struct return (0); } - msleep(tq, &tq->tq_mtx, PWAIT, "bored", 0); + tqsleep(tq, &tq->tq_mtx, PWAIT, "bored", 0); } TAILQ_REMOVE(&tq->tq_worklist, next, t_entry); @@ -252,14 +273,20 @@ taskq_next_work(struct taskq *tq, struct void taskq_thread(void *xtq) { + sleepfn tqsleep = msleep; struct taskq *tq = xtq; struct task work; int last; - if (tq->tq_unlocked) + if (ISSET(tq->tq_flags, TASKQ_MPSAFE)) KERNEL_UNLOCK(); - while (taskq_next_work(tq, &work)) { + if (ISSET(tq->tq_flags, TASKQ_CANTSLEEP)) { + tqsleep = taskq_sleep; + atomic_setbits_int(&curproc->p_flag, P_CANTSLEEP); + } + + while (taskq_next_work(tq, &work, tqsleep)) { (*work.t_func)(work.t_arg); sched_pause(); } @@ -268,8 +295,11 @@ taskq_thread(void *xtq) last = (--tq->tq_running == 0); mtx_leave(&tq->tq_mtx); - if (tq->tq_unlocked) + if (ISSET(tq->tq_flags, TASKQ_MPSAFE)) KERNEL_LOCK(); + + if (ISSET(tq->tq_flags, TASKQ_CANTSLEEP)) + atomic_clearbits_int(&curproc->p_flag, P_CANTSLEEP); if (last) wakeup_one(&tq->tq_running); Index: sys/proc.h =================================================================== RCS file: /cvs/src/sys/sys/proc.h,v retrieving revision 1.194 diff -u -p -r1.194 proc.h --- sys/proc.h 26 Jan 2015 22:51:37 -0000 1.194 +++ sys/proc.h 8 Feb 2015 09:55:03 -0000 @@ -364,6 +364,8 @@ struct proc { #define P_PROFPEND 0x000002 /* SIGPROF needs to be posted */ #define P_ALRMPEND 0x000004 /* SIGVTALRM needs to be posted */ #define P_SIGSUSPEND 0x000008 /* Need to restore before-suspend mask*/ + +#define P_CANTSLEEP 0x000010 /* insomniac thread */ #define P_SELECT 0x000040 /* Selecting; wakeup/waiting danger. */ #define P_SINTR 0x000080 /* Sleep is interruptible. */ #define P_SYSTEM 0x000200 /* No sigs, stats or swapping. */ @@ -379,7 +381,7 @@ struct proc { #define P_CPUPEG 0x40000000 /* Do not move to another cpu. */ #define P_BITS \ - ("\20\01INKTR\02PROFPEND\03ALRMPEND\04SIGSUSPEND\07SELECT" \ + ("\20\01INKTR\02PROFPEND\03ALRMPEND\04SIGSUSPEND\05CANTSLEEP\07SELECT" \ "\010SINTR\012SYSTEM" \ "\013TIMEOUT\016WEXIT\020OWEUPC\024SUSPSINGLE" \ "\027SYSTRACE\030CONTINUED\033THREAD" \ Index: sys/task.h =================================================================== RCS file: /cvs/src/sys/sys/task.h,v retrieving revision 1.7 diff -u -p -r1.7 task.h --- sys/task.h 27 Jan 2015 03:17:37 -0000 1.7 +++ sys/task.h 8 Feb 2015 09:55:03 -0000 @@ -30,11 +30,14 @@ struct task { unsigned int t_flags; }; +#define TASKQ_MPSAFE (1 << 0) +#define TASKQ_CANTSLEEP (1 << 1) + #ifdef _KERNEL extern struct taskq *const systq; extern struct taskq *const systqmp; -struct taskq *taskq_create(const char *, unsigned int, int); +struct taskq *taskq_create(const char *, unsigned int, int, unsigned int); void taskq_destroy(struct taskq *); void task_set(struct task *, void (*)(void *), void *);