43#include "opt_device_polling.h"
44#include "opt_hwpmc_hooks.h"
46#include "opt_watchdog.h"
50#include <sys/callout.h>
52#include <sys/eventhandler.h>
53#include <sys/gtaskqueue.h>
55#include <sys/kernel.h>
56#include <sys/kthread.h>
61#include <sys/resource.h>
62#include <sys/resourcevar.h>
65#include <sys/signalvar.h>
66#include <sys/sleepqueue.h>
71#include <sys/sysctl.h>
73#include <sys/interrupt.h>
74#include <sys/limits.h>
75#include <sys/timetc.h>
82#include <sys/pmckern.h>
83PMC_SOFT_DEFINE( , ,
clock, hard);
84PMC_SOFT_DEFINE( , ,
clock, stat);
85PMC_SOFT_DEFINE_EX( , ,
clock, prof, \
103 long cp_time[CPUSTATES];
106 unsigned int cp_time32[CPUSTATES];
111 if (req->flags & SCTL_MASK32) {
113 return SYSCTL_OUT(req, 0,
sizeof(cp_time32));
114 for (i = 0; i < CPUSTATES; i++)
115 cp_time32[i] = (
unsigned int)cp_time[i];
116 error = SYSCTL_OUT(req, cp_time32,
sizeof(cp_time32));
121 return SYSCTL_OUT(req, 0,
sizeof(cp_time));
122 error = SYSCTL_OUT(req, cp_time,
sizeof(cp_time));
127SYSCTL_PROC(_kern, OID_AUTO, cp_time, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,
140 unsigned int cp_time32[CPUSTATES];
146 if (req->flags & SCTL_MASK32)
147 return SYSCTL_OUT(req, 0,
sizeof(cp_time32) * (
mp_maxid + 1));
150 return SYSCTL_OUT(req, 0,
sizeof(
long) * CPUSTATES * (
mp_maxid + 1));
152 for (error = 0, c = 0; error == 0 && c <=
mp_maxid; c++) {
153 if (!CPU_ABSENT(c)) {
155 cp_time = pcpu->pc_cp_time;
160 if (req->flags & SCTL_MASK32) {
161 for (i = 0; i < CPUSTATES; i++)
162 cp_time32[i] = (
unsigned int)cp_time[i];
163 error = SYSCTL_OUT(req, cp_time32,
sizeof(cp_time32));
166 error = SYSCTL_OUT(req, cp_time,
sizeof(
long) * CPUSTATES);
171SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,
175static const char *
blessed[] = {
181static int slptime_threshold = 1800;
182static int blktime_threshold = 900;
183static int sleepfreq = 3;
186deadlres_td_on_lock(
struct proc *p,
struct thread *td,
int blkticks)
191 PROC_LOCK_ASSERT(p, MA_OWNED);
192 THREAD_LOCK_ASSERT(td, MA_OWNED);
197 MPASS(td->td_blocked != NULL);
199 tticks =
ticks - td->td_blktick;
200 if (tticks > blkticks)
205 panic(
"%s: possible deadlock detected for %p (%s), "
206 "blocked for %d ticks\n", __func__,
211deadlres_td_sleep_q(
struct proc *p,
struct thread *td,
int slpticks)
214 int i, slptype, tticks;
217 PROC_LOCK_ASSERT(p, MA_OWNED);
218 THREAD_LOCK_ASSERT(td, MA_OWNED);
224 wchan = td->td_wchan;
225 tticks =
ticks - td->td_slptick;
227 if ((slptype == SLEEPQ_SX || slptype == SLEEPQ_LK) &&
235 for (i = 0;
blessed[i] != NULL; i++)
236 if (!strcmp(
blessed[i], td->td_wmesg))
239 panic(
"%s: possible deadlock detected for %p (%s), "
240 "blocked for %d ticks\n", __func__,
250 int blkticks, slpticks, tryl;
254 blkticks = blktime_threshold *
hz;
255 slpticks = slptime_threshold *
hz;
265 panic(
"%s: possible deadlock detected "
266 "on allproc_lock\n", __func__);
268 pause(
"allproc", sleepfreq *
hz);
272 FOREACH_PROC_IN_SYSTEM(p) {
274 if (p->p_state == PRS_NEW) {
278 FOREACH_THREAD_IN_PROC(p, td) {
281 deadlres_td_on_lock(p, td,
283 else if (TD_IS_SLEEPING(td))
284 deadlres_td_sleep_q(p, td,
293 pause(
"-", sleepfreq *
hz);
297static struct kthread_desc deadlkres_kd = {
300 (
struct thread **)NULL
305static SYSCTL_NODE(_debug, OID_AUTO, deadlkres, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
306 "Deadlock resolver");
307SYSCTL_INT(_debug_deadlkres, OID_AUTO, slptime_threshold, CTLFLAG_RW,
308 &slptime_threshold, 0,
309 "Number of seconds within is valid to sleep on a sleepqueue");
310SYSCTL_INT(_debug_deadlkres, OID_AUTO, blktime_threshold, CTLFLAG_RW,
311 &blktime_threshold, 0,
312 "Number of seconds within is valid to block on a turnstile");
313SYSCTL_INT(_debug_deadlkres, OID_AUTO, sleepfreq, CTLFLAG_RW, &sleepfreq, 0,
314 "Number of seconds between any deadlock resolver thread run");
324 bzero(cp_time,
sizeof(
long) * CPUSTATES);
327 for (j = 0; j < CPUSTATES; j++)
328 cp_time[j] += pc->pc_cp_time[j];
332#include <sys/watchdog.h>
385static int devpoll_run = 0;
400 mtx_init(&
time_lock,
"time lock", NULL, MTX_DEF);
416 if (wdog_software_attach == NULL)
422static __noinline
void
431 timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) {
433 if (
itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL],
435 flags |= TDF_ALRMPEND | TDF_ASTPENDING;
438 if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) {
442 flags |= TDF_PROFPEND | TDF_ASTPENDING;
447 td->td_flags |=
flags;
455 struct pstats *pstats;
456 struct thread *td = curthread;
457 struct proc *p = td->td_proc;
458 int *t = DPCPU_PTR(pcputicks);
459 int global, i, newticks;
467 newticks = *t - global;
474 }
while (!atomic_fcmpset_int(&
ticks, &global, *t));
481 timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) ||
482 timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)))
486 if (PMC_CPU_HAS_SAMPLES(PCPU_GET(cpuid)))
487 PMC_CALL_HOOK_UNLOCKED(curthread, PMC_FN_DO_SAMPLES, NULL);
488 if (td->td_intr_frame != NULL)
489 PMC_SOFT_CALL_TF( , ,
clock, hard, td->td_intr_frame);
496 if (atomic_cmpset_acq_int(&devpoll_run, 0, 1)) {
499 atomic_store_rel_int(&devpoll_run, 0);
504 if (i > 0 && i <= newticks)
509 if (curcpu == CPU_FIRST())
511 if (__predict_false(DPCPU_GET(epoch_cb_count)))
512 GROUPTASK_ENQUEUE(DPCPU_PTR(epoch_cb_task));
519 KASSERT(!CPU_ABSENT(cpu), (
"Absent CPU %d", cpu));
520 t = DPCPU_ID_PTR(cpu, pcputicks);
566 printf(
"tvotohz: negative time difference %ld sec %ld usec\n",
570 }
else if (sec <= LONG_MAX / 1000000)
571 ticks = howmany(sec * 1000000 + (
unsigned long)usec,
tick) + 1;
572 else if (sec <= LONG_MAX /
hz)
574 + howmany((
unsigned long)usec,
tick) + 1;
592 PROC_LOCK_ASSERT(p, MA_OWNED);
593 if (p->p_flag & P_STOPPROF)
595 if ((p->p_flag & P_PROFIL) == 0) {
596 p->p_flag |= P_PROFIL;
611 PROC_LOCK_ASSERT(p, MA_OWNED);
612 if (p->p_flag & P_PROFIL) {
613 if (p->p_profthreads != 0) {
614 while (p->p_profthreads != 0) {
615 p->p_flag |= P_STOPPROF;
616 msleep(&p->p_profthreads, &p->p_mtx, PPAUSE,
620 if ((p->p_flag & P_PROFIL) == 0)
622 p->p_flag &= ~P_PROFIL;
645 uint64_t runtime, new_switchtime;
650 cp_time = (
long *)PCPU_PTR(cp_time);
655 td->td_uticks += cnt;
656 if (p->p_nice > NZERO)
657 cp_time[CP_NICE] += cnt;
659 cp_time[CP_USER] += cnt;
673 if ((td->td_pflags & TDP_ITHREAD) ||
674 td->td_intr_nesting_level >= 2) {
675 td->td_iticks += cnt;
676 cp_time[CP_INTR] += cnt;
678 td->td_pticks += cnt;
679 td->td_sticks += cnt;
680 if (!TD_IS_IDLETHREAD(td))
681 cp_time[CP_SYS] += cnt;
683 cp_time[CP_IDLE] += cnt;
688 MPASS(p->p_vmspace != NULL);
691 ru->ru_ixrss += pgtok(vm->vm_tsize) * cnt;
692 ru->ru_idrss += pgtok(vm->vm_dsize) * cnt;
693 ru->ru_isrss += pgtok(vm->vm_ssize) * cnt;
694 rss = pgtok(vmspace_resident_count(vm));
695 if (ru->ru_maxrss < rss)
697 KTR_POINT2(KTR_SCHED,
"thread",
sched_tdname(td),
"statclock",
699 SDT_PROBE2(sched, , ,
tick, td, td->td_proc);
700 thread_lock_flags(td, MTX_QUIET);
707 runtime = new_switchtime - PCPU_GET(switchtime);
708 td->td_runtime += runtime;
709 td->td_incruntime += runtime;
710 PCPU_SET(switchtime, new_switchtime);
715 if (td->td_intr_frame != NULL)
716 PMC_SOFT_CALL_TF( , ,
clock, stat, td->td_intr_frame);
737 if (td->td_proc->p_flag & P_PROFIL)
746 if (g->state == GMON_PROF_ON && pc >= g->lowpc) {
748 if (i < g->textsize) {
755 if (td->td_intr_frame != NULL)
756 PMC_SOFT_CALL_TF( , ,
clock, prof, td->td_intr_frame);
766 struct clockinfo clkinfo;
770 bzero(&clkinfo,
sizeof(clkinfo));
779 CTLTYPE_STRUCT|CTLFLAG_RD|CTLFLAG_MPSAFE,
781 "Rate and period of various kernel clocks");
788 u = cmd & WD_INTERVAL;
789 if (u >= WD_TO_1SEC) {
813 nintr = sintrcnt /
sizeof(u_long);
815 printf(
"interrupt total\n");
816 while (--nintr >= 0) {
818 printf(
"%-12s %20lu\n", curname, *curintr);
819 curname += strlen(curname) + 1;
820 inttotal += *curintr++;
822 printf(
"Total %20ju\n", (uintmax_t)inttotal);
824#if defined(KDB) && !defined(KDB_UNATTENDED)
826 kdb_enter(KDB_WHY_WATCHDOG,
"watchdog timeout");
828 panic(
"watchdog timeout");
SYSCTL_NODE(_kern, OID_AUTO, binmisc, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "Image activator for miscellaneous binaries")
SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, enable, CTLFLAG_RWTUN, &__elfN(aslr_enabled), 0, ": enable address map randomization")
static void watchdog_config(void *, u_int, int *)
void hardclock_sync(int cpu)
static int watchdog_ticks
SDT_PROBE_DEFINE2(sched,,, tick, "struct thread *", "struct proc *")
void read_cpu_time(long *cp_time)
static int sysctl_kern_cp_time(SYSCTL_HANDLER_ARGS)
int tvtohz(struct timeval *tv)
void stopprofclock(struct proc *p)
SDT_PROVIDER_DECLARE(sched)
static __noinline void hardclock_itimer(struct thread *td, struct pstats *pstats, int cnt, int usermode)
static void watchdog_fire(void)
static int sysctl_kern_clockrate(SYSCTL_HANDLER_ARGS)
static int sysctl_kern_cp_times(SYSCTL_HANDLER_ARGS)
static void watchdog_attach(void)
void profclock(int cnt, int usermode, uintfptr_t pc)
SYSCTL_PROC(_kern, OID_AUTO, cp_time, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE, 0, 0, sysctl_kern_cp_time, "LU", "CPU time statistics")
void statclock(int cnt, int usermode)
static int watchdog_enabled
static long empty[CPUSTATES]
SYSINIT(clocks, SI_SUB_CLOCKS, SI_ORDER_FIRST, initclocks, NULL)
void hardclock(int cnt, int usermode)
void startprofclock(struct proc *p)
DPCPU_DEFINE_STATIC(int, pcputicks)
static void initclocks(void *dummy __unused)
static struct mtx time_lock
void cpu_stopprofclock(void)
void cpu_startprofclock(void)
int intr_event_handle(struct intr_event *ie, struct trapframe *frame)
struct intr_event * clk_intr_event
void kthread_start(const void *udata)
void hardclock_device_poll(void)
struct sx __exclusive_cache_line allproc_lock
void panic(const char *fmt,...)
int sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
void tc_ticktock(int cnt)
void cpu_tick_calibration(void)
int itimerdecr(struct itimerval *itp, int usec)
void sched_clock(struct thread *td, int cnt)
char * sched_tdname(struct thread *td)
void kdb_enter(const char *why, const char *msg)
struct pcpu * pcpu_find(u_int cpuid)
int printf(const char *fmt,...)
void addupc_intr(struct thread *td, uintfptr_t pc, u_int ticks)
int sleepq_type(const void *wchan)
static int blessed(struct witness *, struct witness *)