tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
DTrace "sched" provider - reviews?
I've taken a stab at implementing the DTrace "sched" provider, for most
of the probes listed here which made sense:
http://dtrace.org/guide/chp-sched.html#tbl-sched
Please note that this was my first foray into the scheduling code, as
well an early effort at implementing a dtrace provider; it's entirely
possible I got big honking things flat-out wrong.
This has been tested to a limited degree; to the effect of making sure
probes fire (though I'm not sure I've tested all of them), and also that
they seem to make some amount of sense. I haven't yet put them through
any great paces.
Any and all feedback welcome.
Index: sys/kern/kern_runq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_runq.c,v
retrieving revision 1.44
diff -u -r1.44 kern_runq.c
--- sys/kern/kern_runq.c 7 Oct 2015 00:32:34 -0000 1.44
+++ sys/kern/kern_runq.c 1 Feb 2016 21:57:28 -0000
@@ -29,7 +29,9 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_runq.c,v 1.44 2015/10/07 00:32:34 christos Exp $");
+#ifdef _KERNEL_OPT
#include "opt_dtrace.h"
+#endif
#include <sys/param.h>
#include <sys/kernel.h>
@@ -47,6 +49,7 @@
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/evcnt.h>
+#include <sys/sdt.h>
/*
* Priority related definitions.
@@ -127,6 +130,13 @@
struct lwp *curthread;
#endif
+SDT_PROVIDER_DECLARE(sched);
+
+SDT_PROBE_DEFINE3(sched, kernel, , dequeue, "struct lwp *",
+ "struct proc *", "struct cpuinfo *");
+SDT_PROBE_DEFINE4(sched, kernel, , enqueue, "struct lwp *",
+ "struct proc *", "struct cpuinfo *", "int");
+
void
runq_init(void)
{
@@ -254,6 +264,7 @@
if (eprio > spc->spc_maxpriority)
spc->spc_maxpriority = eprio;
+ SDT_PROBE4(sched, kernel, , enqueue, l, l->l_proc, ci, 0);
sched_newts(l);
/*
@@ -296,6 +307,7 @@
ci_rq->r_mcount--;
q_head = sched_getrq(ci_rq, eprio);
+ SDT_PROBE3(sched, kernel, , dequeue, l, l->l_proc, NULL);
TAILQ_REMOVE(q_head, l, l_runq);
if (TAILQ_EMPTY(q_head)) {
u_int i;
Index: sys/kern/kern_sleepq.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_sleepq.c,v
retrieving revision 1.50
diff -u -r1.50 kern_sleepq.c
--- sys/kern/kern_sleepq.c 5 Sep 2014 05:57:21 -0000 1.50
+++ sys/kern/kern_sleepq.c 1 Feb 2016 21:57:28 -0000
@@ -34,6 +34,10 @@
* interfaces.
*/
+#ifdef _KERNEL_OPT
+#include "opt_dtrace.h"
+#endif
+
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.50 2014/09/05 05:57:21 matt Exp $");
@@ -48,6 +52,7 @@
#include <sys/systm.h>
#include <sys/sleepq.h>
#include <sys/ktrace.h>
+#include <sys/sdt.h>
/*
* for sleepq_abort:
@@ -62,6 +67,12 @@
#define IPL_SAFEPRI 0
#endif
+SDT_PROVIDER_DECLARE(sched);
+
+SDT_PROBE_DEFINE2(sched, kernel, , wakeup, "struct lwp *",
+ "struct proc *");
+SDT_PROBE_DEFINE(sched, kernel, , sleep);
+
static int sleepq_sigtoerror(lwp_t *, int);
/* General purpose sleep table, used by mtsleep() and condition variables. */
@@ -143,6 +154,7 @@
/* Update sleep time delta, call the wake-up handler of scheduler */
l->l_slpticksum += (hardclock_ticks - l->l_slpticks);
+ SDT_PROBE2(sched, kernel, , wakeup, l, l->l_proc);
sched_wakeup(l);
/* Look for a CPU to wake up */
@@ -217,6 +229,7 @@
/* Save the time when thread has slept */
l->l_slpticks = hardclock_ticks;
+ SDT_PROBE0(sched, kernel, , sleep);
sched_slept(l);
}
Index: sys/kern/kern_synch.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_synch.c,v
retrieving revision 1.309
diff -u -r1.309 kern_synch.c
--- sys/kern/kern_synch.c 13 Oct 2015 00:25:51 -0000 1.309
+++ sys/kern/kern_synch.c 1 Feb 2016 21:57:28 -0000
@@ -71,9 +71,11 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.309 2015/10/13 00:25:51 pgoyette Exp $");
+#ifdef _KERNEL_OPT
#include "opt_kstack.h"
#include "opt_perfctrs.h"
#include "opt_dtrace.h"
+#endif
#define __MUTEX_PRIVATE
@@ -96,6 +98,7 @@
#include <sys/lwpctl.h>
#include <sys/atomic.h>
#include <sys/syslog.h>
+#include <sys/sdt.h>
#include <uvm/uvm_extern.h>
@@ -105,6 +108,14 @@
int dtrace_vtime_active=0;
dtrace_vtime_switch_func_t dtrace_vtime_switch_func;
+SDT_PROVIDER_DEFINE(sched);
+
+SDT_PROBE_DEFINE2(sched, kernel, , off__cpu, "struct lwp *",
+ "struct proc *");
+SDT_PROBE_DEFINE(sched, kernel, , on__cpu);
+SDT_PROBE_DEFINE(sched, kernel, , preempt);
+SDT_PROBE_DEFINE(sched, kernel, , remain__cpu);
+
static void sched_unsleep(struct lwp *, bool);
static void sched_changepri(struct lwp *, pri_t);
static void sched_lendpri(struct lwp *, pri_t);
@@ -296,6 +307,7 @@
KASSERT(l->l_stat == LSONPROC);
l->l_kpriority = false;
l->l_nivcsw++;
+ SDT_PROBE0(sched, kernel, , preempt);
(void)mi_switch(l);
KERNEL_LOCK(l->l_biglocks, l);
}
@@ -638,6 +650,7 @@
if (l != newl) {
struct lwp *prevlwp;
+ SDT_PROBE2(sched, kernel, , off__cpu, newl, newl->l_proc);
/* Release all locks, but leave the current LWP locked */
if (l->l_mutex == spc->spc_mutex) {
/*
@@ -731,6 +744,7 @@
pmap_activate(l);
uvm_emap_switch(l);
pcu_switchpoint(l);
+ SDT_PROBE0(sched, kernel, , on__cpu);
if (prevlwp != NULL) {
/* Normalize the count of the spin-mutexes */
@@ -760,6 +774,7 @@
/* Nothing to do - just unlock and return. */
mutex_spin_exit(spc->spc_mutex);
lwp_unlock(l);
+ SDT_PROBE0(sched, kernel, , remain__cpu);
retval = 0;
}
Index: sys/kern/sched_4bsd.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sched_4bsd.c,v
retrieving revision 1.30
diff -u -r1.30 sched_4bsd.c
--- sys/kern/sched_4bsd.c 24 Jun 2014 10:08:45 -0000 1.30
+++ sys/kern/sched_4bsd.c 1 Feb 2016 21:57:28 -0000
@@ -70,9 +70,12 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sched_4bsd.c,v 1.30 2014/06/24 10:08:45 maxv Exp $");
+#ifdef _KERNEL_OPT
#include "opt_ddb.h"
+#include "opt_dtrace.h"
#include "opt_lockdebug.h"
#include "opt_perfctrs.h"
+#endif
#include <sys/param.h>
#include <sys/systm.h>
@@ -88,6 +91,14 @@
#include <sys/lockdebug.h>
#include <sys/kmem.h>
#include <sys/intr.h>
+#include <sys/sdt.h>
+
+SDT_PROVIDER_DECLARE(sched);
+
+SDT_PROBE_DEFINE3(sched, kernel, , change__pri, "struct lwp *",
+ "struct proc *", "pri_t");
+SDT_PROBE_DEFINE2(sched, kernel, , tick, "struct lwp *",
+ "struct proc *");
static void updatepri(struct lwp *);
static void resetpriority(struct lwp *);
@@ -121,6 +132,7 @@
if (l == NULL) {
return;
}
+ SDT_PROBE2(sched, kernel, , tick, l, l->l_proc);
switch (l->l_class) {
case SCHED_FIFO:
/* No timeslicing for FIFO jobs. */
@@ -369,8 +381,10 @@
/* See comments above ESTCPU_SHIFT definition. */
pri = (PRI_KERNEL - 1) - (l->l_estcpu >> ESTCPU_SHIFT) - p->p_nice;
pri = imax(pri, 0);
- if (pri != l->l_priority)
+ if (pri != l->l_priority) {
+ SDT_PROBE3(sched, kernel, , change__pri, l, l->l_proc, pri);
lwp_changepri(l, pri);
+ }
}
/*
Index: sys/kern/sched_m2.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sched_m2.c,v
retrieving revision 1.32
diff -u -r1.32 sched_m2.c
--- sys/kern/sched_m2.c 24 Jun 2014 10:08:45 -0000 1.32
+++ sys/kern/sched_m2.c 1 Feb 2016 21:57:28 -0000
@@ -35,6 +35,10 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sched_m2.c,v 1.32 2014/06/24 10:08:45 maxv Exp $");
+#ifdef _KERNEL_OPT
+#include "opt_dtrace.h"
+#endif
+
#include <sys/param.h>
#include <sys/cpu.h>
@@ -53,6 +57,7 @@
#include <sys/syscallargs.h>
#include <sys/sysctl.h>
#include <sys/types.h>
+#include <sys/sdt.h>
/*
* Priority related definitions.
@@ -74,6 +79,14 @@
static void sched_precalcts(void);
+/* DTrace probes */
+SDT_PROVIDER_DECLARE(sched);
+
+SDT_PROBE_DEFINE3(sched, kernel, , change__pri, "struct lwp *",
+ "struct proc *", "pri_t");
+SDT_PROBE_DEFINE2(sched, kernel, , tick, "struct lwp *",
+ "struct proc *");
+
/*
* Initialization and setup.
*/
@@ -190,6 +203,8 @@
if (l->l_class == SCHED_OTHER) {
pri_t pri = l->l_priority - n;
pri = (n < 0) ? min(pri, PRI_HIGHEST_TS) : imax(pri, 0);
+ SDT_PROBE3(sched, kernel, , change__pri, l,
+ l->l_proc, pri);
lwp_changepri(l, pri);
}
lwp_unlock(l);
@@ -253,6 +268,7 @@
if (batch && prio != 0)
prio--;
+ SDT_PROBE3(sched, kernel, , change__pri, l, l->l_proc, prio);
/* If thread was not ran a second or more - set a high priority */
if (l->l_stat == LSRUN) {
if (l->l_rticks && (hardclock_ticks - l->l_rticks >= hz))
@@ -295,6 +311,7 @@
if (__predict_false(CURCPU_IDLE_P()))
return;
+ SDT_PROBE2(sched, kernel, , tick, l, l->l_proc);
switch (l->l_class) {
case SCHED_FIFO:
/*
Home |
Main Index |
Thread Index |
Old Index