crit_enter();
tsleep_interlock(ident);
lockmgr(lock, LK_RELEASE);
+ retval = tsleep(ident, flags | PINTERLOCKED, wmesg, timo);
+ } else {
+ retval = tsleep(ident, flags, wmesg, timo);
}
- retval = tsleep(ident, flags, wmesg, timo);
-
if (lock != &sim_mplock) {
lockmgr(lock, LK_EXCLUSIVE);
crit_exit();
crit_enter();
tsleep_interlock(&xsoftc.ccb_scanq);
xpt_unlock_buses();
- tsleep(&xsoftc.ccb_scanq, 0, "ccb_scanq", 0);
+ tsleep(&xsoftc.ccb_scanq, PINTERLOCKED, "ccb_scanq", 0);
crit_exit();
}
}
crit_enter();
tsleep_interlock(&ap->ap_thread);
if (ap->ap_signal == 0)
- tsleep(&ap->ap_thread, 0, "ahport", 0);
+ tsleep(&ap->ap_thread, PINTERLOCKED, "ahport", 0);
crit_exit();
mask = ap->ap_signal;
}
aic_lock(aic);
tsleep_interlock(aic->platform_data);
aic_unlock(aic);
- tsleep(aic->platform_data, 0, "thtrm", 0);
+ tsleep(aic->platform_data, PINTERLOCKED, "thtrm", 0);
crit_exit();
}
crit_enter();
tsleep_interlock(aic);
aic_unlock(aic);
- tsleep(aic, 0, "idle", 0);
+ tsleep(aic, PINTERLOCKED, "idle", 0);
aic_lock(aic);
crit_exit();
}
crit_enter();
tsleep_interlock(&ap->ap_thread);
if (ap->ap_signal == 0)
- tsleep(&ap->ap_thread, 0, "ahport", 0);
+ tsleep(&ap->ap_thread, PINTERLOCKED, "ahport", 0);
crit_exit();
mask = ap->ap_signal;
}
crit_enter(); \
tsleep_interlock(&(queue)); \
lwkt_serialize_exit(&dev->irq_lock); \
- ret = -tsleep(&(queue), PCATCH, \
+ ret = -tsleep(&(queue), PCATCH | PINTERLOCKED, \
"drmwtq", (timeout)); \
crit_exit(); \
} else { \
tsleep_interlock((void *)&dev->lock.lock_queue);
DRM_UNLOCK();
retcode = tsleep((void *)&dev->lock.lock_queue,
- PCATCH, "drmlk2", 0);
+ PCATCH | PINTERLOCKED, "drmlk2", 0);
crit_exit();
DRM_LOCK();
if (retcode)
crit_enter();
tsleep_interlock((void *)&dev->lock.lock_queue);
DRM_UNLOCK();
- ret = tsleep((void *)&dev->lock.lock_queue, PCATCH,
- "drmlk2", 0);
+ ret = tsleep((void *)&dev->lock.lock_queue,
+ PCATCH | PINTERLOCKED, "drmlk2", 0);
crit_exit();
DRM_LOCK();
if (ret != 0)
while ((ret = r600_do_cp_idle(dev_priv)) != 0) {
DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
crit_enter();
- tsleep_interlock((void *)&dev->lock.lock_queue);
+ tsleep_interlock(&dev->lock.lock_queue);
DRM_UNLOCK();
- ret = tsleep((void *)&dev->lock.lock_queue, PCATCH,
- "rdnrel", 0);
+ ret = tsleep(&dev->lock.lock_queue,
+ PCATCH | PINTERLOCKED,
+ "rdnrel", 0);
crit_exit();
DRM_LOCK();
}
while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
crit_enter();
- tsleep_interlock((void *)&dev->lock.lock_queue);
+ tsleep_interlock(&dev->lock.lock_queue);
DRM_UNLOCK();
- ret = tsleep((void *)&dev->lock.lock_queue, PCATCH,
- "rdnrel", 0);
+ ret = tsleep(&dev->lock.lock_queue,
+ PCATCH | PINTERLOCKED,
+ "rdnrel", 0);
crit_exit();
DRM_LOCK();
}
tsleep_interlock(IWI_FW_WAKE_MONITOR(sc));
lwkt_serialize_exit(ifp->if_serializer);
error = tsleep(IWI_FW_WAKE_MONITOR(sc),
- 0, "iwifwm", 0);
+ PINTERLOCKED, "iwifwm", 0);
crit_exit();
lwkt_serialize_enter(ifp->if_serializer);
}
crit_enter();
tsleep_interlock(IWI_FW_CMD_ACKED(sc));
lwkt_serialize_exit(ifp->if_serializer);
- error = tsleep(IWI_FW_CMD_ACKED(sc), 0,
+ error = tsleep(IWI_FW_CMD_ACKED(sc),
+ PINTERLOCKED,
"iwirun", boff * hz);
crit_exit();
lwkt_serialize_enter(ifp->if_serializer);
crit_enter();
tsleep_interlock(IWI_FW_EXIT_MONITOR(sc));
lwkt_serialize_exit(ifp->if_serializer);
- tsleep(IWI_FW_EXIT_MONITOR(sc), 0, "iwiexi", 0);
+ tsleep(IWI_FW_EXIT_MONITOR(sc), PINTERLOCKED, "iwiexi", 0);
crit_exit();
/* No need to hold serializer again */
crit_enter();
tsleep_interlock(IWI_FW_CMD_ACKED(sc));
lwkt_serialize_exit(ifp->if_serializer);
- ret = tsleep(IWI_FW_CMD_ACKED(sc), 0, "iwicmd", hz);
+ ret = tsleep(IWI_FW_CMD_ACKED(sc), PINTERLOCKED, "iwicmd", hz);
crit_exit();
lwkt_serialize_enter(ifp->if_serializer);
} else {
crit_enter();
tsleep_interlock(IWI_FW_INITIALIZED(sc));
lwkt_serialize_exit(ifp->if_serializer);
- error = tsleep(IWI_FW_INITIALIZED(sc), 0, "iwiinit", hz);
+ error = tsleep(IWI_FW_INITIALIZED(sc), PINTERLOCKED, "iwiinit", hz);
crit_exit();
lwkt_serialize_enter(ifp->if_serializer);
if (error != 0) {
crit_enter();
tsleep_interlock(sc->aifthread);
AAC_LOCK_RELEASE(&sc->aac_io_lock);
- retval = tsleep(sc->aifthread, 0,
+ retval = tsleep(sc->aifthread, PINTERLOCKED,
"aifthd", AAC_PERIODIC_INTERVAL * hz);
AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
crit_exit();
crit_enter();
tsleep_interlock(cm);
AAC_LOCK_RELEASE(&sc->aac_io_lock);
- error = tsleep(cm, 0, "aacwait", 0);
+ error = tsleep(cm, PINTERLOCKED, "aacwait", 0);
AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
crit_exit();
return(error);
crit_enter();
tsleep_interlock(&cm);
AAC_LOCK_RELEASE(&sc->aac_io_lock);
- tsleep(&cm, 0, "sendfib", 0);
+ tsleep(&cm, PINTERLOCKED, "sendfib", 0);
AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
crit_exit();
}
crit_enter();
tsleep_interlock(addr);
snd_mtxunlock(lock);
- r = tsleep(addr, flags, wmesg, timo);
+ r = tsleep(addr, flags | PINTERLOCKED, wmesg, timo);
snd_mtxlock(lock);
crit_exit();
return(r);
KTR_INFO(KTR_TSLEEP, tsleep, tsleep_end, 1, "tsleep exit", 0);
KTR_INFO(KTR_TSLEEP, tsleep, wakeup_beg, 2, "wakeup enter %p", sizeof(void *));
KTR_INFO(KTR_TSLEEP, tsleep, wakeup_end, 3, "wakeup exit", 0);
+KTR_INFO(KTR_TSLEEP, tsleep, ilockfail, 4, "interlock failed %p", sizeof(void *));
#define logtsleep1(name) KTR_LOG(tsleep_ ## name)
#define logtsleep2(name, val) KTR_LOG(tsleep_ ## name, val)
}
/*
+ * If the interlocked flag is set but our cpu bit in the slpqueue
+ * is no longer set, then a wakeup was processed inbetween the
+ * tsleep_interlock() and here. This can occur under extreme loads
+ * if the IPIQ fills up and gets processed synchronously by, say,
+ * a wakeup() or other IPI sent inbetween the interlock and here.
+ *
+ * Even the usched->release function just above can muff it up.
+ */
+ if ((flags & PINTERLOCKED) &&
+ (slpque_cpumasks[id] & gd->gd_cpumask) == 0) {
+ logtsleep2(ilockfail, ident);
+ goto resume;
+ }
+
+ /*
* Move our thread to the correct queue and setup our wchan, etc.
*/
lwkt_deschedule_self(td);
if (*(int *)(sf_buf_kva(sf) + offset) == uap->value) {
vm_page_init_action(&action, umtx_sleep_page_action_cow, waddr);
vm_page_register_action(m, &action, VMEVENT_COW);
- error = tsleep(waddr, PCATCH|PDOMAIN_UMTX, "umtxsl", timeout);
+ error = tsleep(waddr, PCATCH | PINTERLOCKED | PDOMAIN_UMTX,
+ "umtxsl", timeout);
vm_page_unregister_action(m, &action);
} else {
error = EBUSY;
while (other_cpumask != 0) {
tsleep_interlock(&other_cpumask);
if (other_cpumask != 0)
- tsleep(&other_cpumask, 0, wmesg, 0);
+ tsleep(&other_cpumask, PINTERLOCKED, wmesg, 0);
}
crit_exit();
}
tsleep_interlock(s);
if (atomic_intr_cond_test(&s->interlock) != 0) {
logslz(sleep_beg, s);
- tsleep(s, 0, "slize", 0);
+ tsleep(s, PINTERLOCKED, "slize", 0);
logslz(sleep_end, s);
}
crit_exit();
tsleep_interlock(s);
if (atomic_intr_cond_test(&s->interlock) != 0) {
logslz(sleep_beg, s);
- tsleep(s, 0, "slize", 0);
+ tsleep(s, PINTERLOCKED, "slize", 0);
logslz(sleep_end, s);
}
crit_exit();
crit_enter();
tsleep_interlock(&devsoftc);
lockmgr(&devsoftc.lock, LK_RELEASE);
- rv = tsleep(&devsoftc, PCATCH, "devctl", 0);
+ rv = tsleep(&devsoftc, PCATCH | PINTERLOCKED, "devctl", 0);
crit_exit();
lockmgr(&devsoftc.lock, LK_EXCLUSIVE);
if (rv) {
crit_enter();
tsleep_interlock(rpipe);
lwkt_reltoken(&wlock);
- error = tsleep(rpipe, PCATCH, "piperd", 0);
+ error = tsleep(rpipe, PCATCH | PINTERLOCKED, "piperd", 0);
crit_exit();
++pipe_rblocked_count;
if (error)
tsleep_interlock(&bd_wake_ary[i]);
spin_unlock_wr(&needsbuffer_spin);
- tsleep(&bd_wake_ary[i], 0, "flstik", hz);
+ tsleep(&bd_wake_ary[i], PINTERLOCKED, "flstik", hz);
crit_exit();
totalspace = runningbufspace + dirtybufspace - hidirtybufspace;
tsleep_interlock(track);
if (active == desired ||
atomic_cmpset_int(&track->bk_active, active, desired)) {
- error = tsleep(track, slp_flags, "iowait", slp_timo);
+ error = tsleep(track, slp_flags | PINTERLOCKED,
+ "iowait", slp_timo);
if (error)
break;
}
if (bp->b_cmd == BUF_CMD_DONE)
break;
if (bp->b_cmd == BUF_CMD_READ)
- tsleep(bp, 0, "biord", 0);
+ tsleep(bp, PINTERLOCKED, "biord", 0);
else
- tsleep(bp, 0, "biowr", 0);
+ tsleep(bp, PINTERLOCKED, "biowr", 0);
}
crit_exit();
}
crit_enter();
tsleep_interlock(&fp->f_flag);
if (atomic_cmpset_int(&fp->f_flag, flags, nflags))
- tsleep(&fp->f_flag, 0, "fpoff", 0);
+ tsleep(&fp->f_flag, PINTERLOCKED, "fpoff", 0);
crit_exit();
} else {
nflags = flags | FOFFSETLOCK;
crit_enter();
tsleep_interlock(tp);
ifnet_deserialize_all(ifp);
- error = tsleep(tp, PCATCH, "taprd", 0);
+ error = tsleep(tp, PCATCH | PINTERLOCKED, "taprd", 0);
crit_exit();
if (error)
return (error);
crit_enter();
tsleep_interlock(chan);
smb_sl_unlock(sl);
- error = tsleep(chan, slpflags, wmesg, timo);
+ error = tsleep(chan, slpflags | PINTERLOCKED, wmesg, timo);
if ((slpflags & PDROP) == 0)
smb_sl_lock(sl);
crit_exit();
#define PCATCH 0x00000100 /* tsleep checks signals */
#define PUSRFLAG1 0x00000200 /* Subsystem specific flag */
+#define PINTERLOCKED 0x00000400 /* Interlocked tsleep */
#define PWAKEUP_CPUMASK 0x00003FFF /* start cpu for chained wakeups */
#define PWAKEUP_MYCPU 0x00004000 /* wakeup on current cpu only */
#define PWAKEUP_ONE 0x00008000 /* argument to wakeup: only one */
tsleep_interlock(io);
io->waiting = 1;
for (;;) {
- tsleep(io, 0, "hmrflw", 0);
+ tsleep(io, PINTERLOCKED, "hmrflw", 0);
if (io->running == 0)
break;
tsleep_interlock(io);
crit_enter();
tsleep_interlock(&bp->b_cmd);
if (bp->b_cmd != BUF_CMD_DONE)
- tsleep(&bp->b_cmd, 0, "hmrFLS", 0);
+ tsleep(&bp->b_cmd, PINTERLOCKED, "hmrFLS", 0);
crit_exit();
}
bp->b_flags &= ~B_ASYNC;
crit_enter();
tsleep_interlock(lock);
if (atomic_cmpset_int(&lock->lockval, lv, nlv)) {
- tsleep(lock, 0, ident, 0);
+ tsleep(lock, PINTERLOCKED, ident, 0);
if (hammer_debug_locks)
kprintf("hammer_lock_ex: try again\n");
}
crit_enter();
tsleep_interlock(lock);
if (atomic_cmpset_int(&lock->lockval, lv, nlv)) {
- tsleep(lock, 0, "hmrlck", 0);
+ tsleep(lock, PINTERLOCKED, "hmrlck", 0);
}
crit_exit();
}