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