diff options
author | rstone <rstone@FreeBSD.org> | 2012-05-15 01:30:25 +0000 |
---|---|---|
committer | rstone <rstone@FreeBSD.org> | 2012-05-15 01:30:25 +0000 |
commit | a059a0e086bd1de7928ae8b3f87dfb0a15f5ae0e (patch) | |
tree | dcd149c6f88df523a30bf4f80f0007085f75f7f5 /sys/kern/sched_4bsd.c | |
parent | 4a10f14855432b1a407764f8593d7d13f741fc3b (diff) | |
download | FreeBSD-src-a059a0e086bd1de7928ae8b3f87dfb0a15f5ae0e.zip FreeBSD-src-a059a0e086bd1de7928ae8b3f87dfb0a15f5ae0e.tar.gz |
Implement the DTrace sched provider. This implementation aims to be
compatible with the sched provider implemented by Solaris and its open-
source derivatives. Full documentation of the sched provider can be found
on Oracle's DTrace wiki pages.
Note that for compatibility with scripts originally written for Solaris,
serveral probes are defined that will never fire. These probes are defined
to fire when Solaris-specific features perform certain actions. As these
features are not present in FreeBSD, the probes can never fire.
Also, I have added a two probes that are not defined in Solaris, lend-pri
and load-change. These probes have been added to make it possible to
collect schedgraph data with DTrace.
Finally, a few probes are defined in Solaris to take a cpuinfo_t *
argument. As it was not immediately clear to me how to translate that to
FreeBSD, currently those probes are passed NULL in place of a cpuinfo_t *.
Sponsored by: Sandvine Incorporated
MFC after: 2 weeks
Diffstat (limited to 'sys/kern/sched_4bsd.c')
-rw-r--r-- | sys/kern/sched_4bsd.c | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 1bd1cdd..bfae580 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/resourcevar.h> #include <sys/sched.h> +#include <sys/sdt.h> #include <sys/smp.h> #include <sys/sysctl.h> #include <sys/sx.h> @@ -244,12 +245,31 @@ SYSCTL_INT(_kern_sched, OID_AUTO, followon, CTLFLAG_RW, "allow threads to share a quantum"); #endif +SDT_PROVIDER_DEFINE(sched); + +SDT_PROBE_DEFINE3(sched, , , change_pri, change-pri, "struct thread *", + "struct proc *", "uint8_t"); +SDT_PROBE_DEFINE3(sched, , , dequeue, dequeue, "struct thread *", + "struct proc *", "void *"); +SDT_PROBE_DEFINE4(sched, , , enqueue, enqueue, "struct thread *", + "struct proc *", "void *", "int"); +SDT_PROBE_DEFINE4(sched, , , lend_pri, lend-pri, "struct thread *", + "struct proc *", "uint8_t", "struct thread *"); +SDT_PROBE_DEFINE2(sched, , , load_change, load-change, "int", "int"); +SDT_PROBE_DEFINE2(sched, , , off_cpu, off-cpu, "struct thread *", + "struct proc *"); +SDT_PROBE_DEFINE(sched, , , on_cpu, on-cpu); +SDT_PROBE_DEFINE(sched, , , remain_cpu, remain-cpu); +SDT_PROBE_DEFINE2(sched, , , surrender, surrender, "struct thread *", + "struct proc *"); + static __inline void sched_load_add(void) { sched_tdcnt++; KTR_COUNTER0(KTR_SCHED, "load", "global load", sched_tdcnt); + SDT_PROBE2(sched, , , load_change, NOCPU, sched_tdcnt); } static __inline void @@ -258,6 +278,7 @@ sched_load_rem(void) sched_tdcnt--; KTR_COUNTER0(KTR_SCHED, "load", "global load", sched_tdcnt); + SDT_PROBE2(sched, , , load_change, NOCPU, sched_tdcnt); } /* * Arrange to reschedule if necessary, taking the priorities and @@ -795,10 +816,13 @@ sched_priority(struct thread *td, u_char prio) KTR_POINT3(KTR_SCHED, "thread", sched_tdname(td), "priority change", "prio:%d", td->td_priority, "new prio:%d", prio, KTR_ATTR_LINKED, sched_tdname(curthread)); + SDT_PROBE3(sched, , , change_pri, td, td->td_proc, prio); if (td != curthread && prio > td->td_priority) { KTR_POINT3(KTR_SCHED, "thread", sched_tdname(curthread), "lend prio", "prio:%d", td->td_priority, "new prio:%d", prio, KTR_ATTR_LINKED, sched_tdname(td)); + SDT_PROBE4(sched, , , lend_pri, td, td->td_proc, prio, + curthread); } THREAD_LOCK_ASSERT(td, MA_OWNED); if (td->td_priority == prio) @@ -987,6 +1011,9 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) if (PMC_PROC_IS_USING_PMCS(td->td_proc)) PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_OUT); #endif + + SDT_PROBE2(sched, , , off_cpu, td, td->td_proc); + /* I feel sleepy */ lock_profile_release_lock(&sched_lock.lock_object); #ifdef KDTRACE_HOOKS @@ -1018,11 +1045,14 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) * needed to, or the thread_wait() or wait() will * need to reap it. */ + + SDT_PROBE0(sched, , , on_cpu); #ifdef HWPMC_HOOKS if (PMC_PROC_IS_USING_PMCS(td->td_proc)) PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_IN); #endif - } + } else + SDT_PROBE0(sched, , , remain_cpu); #ifdef SMP if (td->td_flags & TDF_IDLETD) @@ -1223,6 +1253,8 @@ sched_add(struct thread *td, int flags) sched_tdname(curthread)); KTR_POINT1(KTR_SCHED, "thread", sched_tdname(curthread), "wokeup", KTR_ATTR_LINKED, sched_tdname(td)); + SDT_PROBE4(sched, , , enqueue, td, td->td_proc, NULL, + flags & SRQ_PREEMPTED); /* @@ -1315,6 +1347,8 @@ sched_add(struct thread *td, int flags) sched_tdname(curthread)); KTR_POINT1(KTR_SCHED, "thread", sched_tdname(curthread), "wokeup", KTR_ATTR_LINKED, sched_tdname(td)); + STD_PROBE4(sched, , , enqueue, td, td->td_proc, NULL, + flags & SRQ_PREEMPTED); /* * Now that the thread is moving to the run-queue, set the lock @@ -1362,6 +1396,7 @@ sched_rem(struct thread *td) KTR_STATE2(KTR_SCHED, "thread", sched_tdname(td), "runq rem", "prio:%d", td->td_priority, KTR_ATTR_LINKED, sched_tdname(curthread)); + SDT_PROBE3(sched, , , dequeue, td, td->td_proc, NULL); if ((td->td_flags & TDF_NOLOAD) == 0) sched_load_rem(); @@ -1425,6 +1460,8 @@ sched_choose(void) void sched_preempt(struct thread *td) { + + SDT_PROBE2(sched, , , surrender, td, td->td_proc); thread_lock(td); if (td->td_critnest > 1) td->td_owepreempt = 1; |