code: plan9front

Download patch

ref: ea3dec6c60c1aac7ff37b0aa4a5130c49ecd480d
parent: f332cf05579e82b213944a331c7b4f37f88f2587
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Aug 13 18:27:52 EDT 2022

dtracy: make timer probes run in interrupt context

When probing a timer, we were running in our own kproc,
and not in an interrupt context, which meant that we didn't
have any access to anything worth sampling, so we didn't
give any data back.

This moves the probe to the hzclock interrupt, and returns
the pc in the probe.

--- a/sys/src/9/port/dtracytimer.c
+++ b/sys/src/9/port/dtracytimer.c
@@ -4,38 +4,37 @@
 #include	"dat.h"
 #include	"fns.h"
 #include	"../port/error.h"
+#include	"ureg.h"
 
 #include	<dtracy.h>
 
 static DTProbe *timerprobe;
+static int	running;
 
-static void
-dtracytimer(void *)
+void
+dtracytick(Ureg *ur)
 {
 	DTTrigInfo info;
 
+	if(!running)
+		return;
 	memset(&info, 0, sizeof(info));
-	for(;;){
-		tsleep(&up->sleep, return0, nil, 1000);
-		dtptrigger(timerprobe, &info);
-	}
+	info.arg[0] = ur->pc;
+	info.arg[1] = userureg(ur);
+	dtptrigger(timerprobe, &info);
 }
 
 static void
 timerprovide(DTProvider *prov)
 {
-	timerprobe = dtpnew("timer::1s", prov, nil);
+	if(timerprobe == nil)
+		timerprobe = dtpnew("timer::1tk", prov, nil);
 }
 
 static int
 timerenable(DTProbe *)
 {
-	static int gotkproc;
-	
-	if(!gotkproc){
-		kproc("dtracytimer", dtracytimer, nil);
-		gotkproc=1;
-	}
+	running = 1;
 	return 0;
 }
 
@@ -42,6 +41,7 @@
 static void
 timerdisable(DTProbe *)
 {
+	running = 0;
 }
 
 DTProvider dtracytimerprov = {
--- a/sys/src/9/port/portclock.c
+++ b/sys/src/9/port/portclock.c
@@ -154,6 +154,7 @@
 	}
 
 	accounttime();
+	dtracytick(ur);
 	kmapinval();
 
 	if(kproftimer != nil)
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -82,6 +82,7 @@
 Dir*		dirchanstat(Chan *);
 void		drawactive(int);
 void		drawcmap(void);
+void		dtracytick(Ureg*);
 void		dumpaproc(Proc*);
 void		dumpregs(Ureg*);
 void		dumpstack(void);