9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Jacob Moody <moody@mail.posixcafe.org>
To: 9front@9front.org
Subject: [9front] [PATCH] teach dtracy how to drive
Date: Sat, 11 Jun 2022 23:46:20 -0600	[thread overview]
Message-ID: <041b6f71-14f3-b478-4981-7d08d762d20e@posixcafe.org> (raw)

This adds "dev" probes to dtracy for tracing
kernel drivers. Ex:

dtracy 'dev:pipe:walk:entry { print pid }'

I quite like this, would be curious what others
think. It does need a bit more testing on other
platforms.

Thanks,
moody

diff c3e1346bbcc2f737ff69fdc353125714ec937ddb uncommitted
--- a//sys/src/9/pc64/pc64
+++ b//sys/src/9/pc64/pc64
@@ -145,6 +145,7 @@

 	dtracysys
 	dtracytimer
+	dtracydev

 ip
 	tcp
--- /dev/null
+++ b//sys/src/9/port/dtracydev.c
@@ -1,0 +1,384 @@
+#include	"u.h"
+#include	"../port/lib.h"
+#include	"mem.h"
+#include	"dat.h"
+#include	"fns.h"
+#include	"../port/error.h"
+
+#include	<dtracy.h>
+
+enum{
+	Dwalk,
+	Dstat,
+	Dopen,
+	Dcreate,
+	Dclose,
+	Dread,
+	Dbread,
+	Dwrite,
+	Dbwrite,
+	Dremove,
+	Dwstat,
+
+	Dend
+};
+
+static char *optab[] = {
+	[Dwalk] "walk",
+	[Dstat] "stat",
+	[Dopen] "open",
+	[Dcreate] "create",
+	[Dclose] "close",
+	[Dread] "read",
+	[Dbread] "bread",
+	[Dwrite] "write",
+	[Dbwrite] "bwrite",
+	[Dremove] "remove",
+	[Dwstat] "wstat",
+};
+
+struct {
+	DTProbe *in[Dend];
+	DTProbe *out[Dend];
+	Dev clean;
+} ledger[256];
+
+static Walkqid*
+wrapwalk(Chan *c, Chan *nc, char **names, int nname)
+{
+	DTTrigInfo info;
+	Walkqid *wq;
+
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)nc;
+	info.arg[2] = (uvlong)names;
+	info.arg[3] = (uvlong)nname;
+	dtptrigger(ledger[c->type].in[Dwalk], &info);
+
+	wq = ledger[c->type].clean.walk(c, nc, names, nname);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)wq;
+	dtptrigger(ledger[c->type].out[Dwalk], &info);
+	return wq;
+}
+
+static int
+wrapstat(Chan *c, uchar *b, int n)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)b;
+	info.arg[2] = (uvlong)n;
+	dtptrigger(ledger[c->type].in[Dstat], &info);
+
+	n = ledger[c->type].clean.stat(c, b, n);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)n;
+	dtptrigger(ledger[c->type].out[Dstat], &info);
+	return n;
+}
+
+static Chan*
+wrapopen(Chan *c, int mode)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)mode;
+	dtptrigger(ledger[c->type].in[Dopen], &info);
+
+	c = ledger[c->type].clean.open(c, mode);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)c;
+	dtptrigger(ledger[c->type].out[Dopen], &info);
+	return c;
+}
+
+static Chan*
+wrapcreate(Chan *c, char *name, int mode, ulong perm)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)name;
+	info.arg[2] = (uvlong)mode;
+	info.arg[3] = (uvlong)perm;
+	dtptrigger(ledger[c->type].in[Dcreate], &info);
+
+	c = ledger[c->type].clean.create(c, name, mode, perm);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)c;
+	dtptrigger(ledger[c->type].out[Dcreate], &info);
+	return c;
+}
+
+static void
+wrapclose(Chan *c)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	dtptrigger(ledger[c->type].in[Dclose], &info);
+
+	ledger[c->type].clean.close(c);
+
+	memset(&info, 0, sizeof info);
+	dtptrigger(ledger[c->type].out[Dclose], &info);
+}
+
+static long
+wrapread(Chan *c, void *b, long n, vlong off)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)b;
+	info.arg[2] = (uvlong)n;
+	info.arg[3] = (uvlong)off;
+	dtptrigger(ledger[c->type].in[Dread], &info);
+
+	n = ledger[c->type].clean.read(c, b, n, off);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)n;
+	dtptrigger(ledger[c->type].out[Dread], &info);
+	return n;
+}
+
+static Block*
+wrapbread(Chan *c, long n, ulong off)
+{
+	Block *b;
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)n;
+	info.arg[2] = (uvlong)off;
+	dtptrigger(ledger[c->type].in[Dbread], &info);
+
+	b = ledger[c->type].clean.bread(c, n, off);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)b;
+	dtptrigger(ledger[c->type].out[Dbread], &info);
+	return b;
+}
+
+static long
+wrapwrite(Chan *c, void *b, long n, vlong off)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)b;
+	info.arg[2] = (uvlong)n;
+	info.arg[3] = (uvlong)off;
+	dtptrigger(ledger[c->type].in[Dwrite], &info);
+
+	n = ledger[c->type].clean.write(c, b, n, off);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)n;
+	dtptrigger(ledger[c->type].out[Dwrite], &info);
+	return n;
+}
+
+static long
+wrapbwrite(Chan *c, Block *b, ulong off)
+{
+	long n;
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)b;
+	info.arg[2] = (uvlong)off;
+	dtptrigger(ledger[c->type].in[Dbwrite], &info);
+
+	n = ledger[c->type].clean.bwrite(c, b, off);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)n;
+	dtptrigger(ledger[c->type].out[Dbwrite], &info);
+	return n;
+}
+
+void
+wrapremove(Chan *c)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	dtptrigger(ledger[c->type].in[Dremove], &info);
+
+	ledger[c->type].clean.remove(c);
+
+	memset(&info, 0, sizeof info);
+	dtptrigger(ledger[c->type].out[Dremove], &info);
+}
+
+int
+wrapwstat(Chan *c, uchar *b, int n)
+{
+	DTTrigInfo info;
+
+	memset(&info, 0, sizeof info);
+	info.arg[0] = (uvlong)c;
+	info.arg[1] = (uvlong)b;
+	info.arg[2] = (uvlong)n;
+	dtptrigger(ledger[c->type].in[Dwstat], &info);
+
+	n = ledger[c->type].clean.wstat(c, b, n);
+
+	memset(&info, 0, sizeof info);
+	info.arg[9] = (uvlong)n;
+	dtptrigger(ledger[c->type].out[Dwstat], &info);
+	return n;
+}
+
+static void
+devprovide(DTProvider *prov)
+{
+	uint i, j;
+	uint path;
+	char pname[32];
+	char buf[32];
+
+	for(i = 0; devtab[i] != nil; i++){
+		memmove(&ledger[i].clean, devtab[i], sizeof(Dev));
+		for(j = 0; j < Dend; j++){
+			path = (i<<16) | j;
+			snprint(buf, sizeof buf, "dev:%s:%s", devtab[i]->name, optab[j]);
+			snprint(pname, sizeof pname, "%s:entry", buf);
+			ledger[i].in[j] = dtpnew(pname, prov, (void *) path);
+			snprint(pname, sizeof pname, "%s:return", buf);
+			ledger[i].out[j] = dtpnew(pname, prov, (void *) path);
+		}
+	}
+}
+
+static int
+devenable(DTProbe *p)
+{
+	uint i, j;
+	uint path;
+	Dev *d;
+	
+	path = (uint)(uintptr)p->aux;
+	i = path>>16;
+	j = path & ((1<<16)-1);
+	assert(i < 256);
+	assert(j < Dend);
+
+	d = devtab[i];
+	switch(j){
+	case Dwalk:
+		d->walk = wrapwalk;
+		break;
+	case Dstat:
+		d->stat = wrapstat;
+		break;
+	case Dopen:
+		d->open = wrapopen;
+		break;
+	case Dcreate:
+		d->create = wrapcreate;
+		break;
+	case Dclose:
+		d->close = wrapclose;
+		break;
+	case Dread:
+		d->read = wrapread;
+		break;
+	case Dbread:
+		d->bread = wrapbread;
+		break;
+	case Dwrite:
+		d->write = wrapwrite;
+		break;
+	case Dbwrite:
+		d->bwrite = wrapbwrite;
+		break;
+	case Dremove:
+		d->remove = wrapremove;
+		break;
+	case Dwstat:
+		d->wstat = wrapwstat;
+		break;
+	}
+	return 0;
+}
+
+static void
+devdisable(DTProbe *p)
+{
+	uint i, j;
+	uint path;
+	Dev *d, *clean;
+	
+	path = (uint)(uintptr)p->aux;
+	i = path>>16;
+	j = path & ((1<<16)-1);
+	assert(i < 256);
+	assert(j < Dend);
+
+	d = devtab[i];
+	clean = &ledger[i].clean;
+	switch(j){
+	case Dwalk:
+		d->walk = clean->walk;
+		break;
+	case Dstat:
+		d->stat = clean->stat;
+		break;
+	case Dopen:
+		d->open = clean->open;
+		break;
+	case Dcreate:
+		d->create = clean->create;
+		break;
+	case Dclose:
+		d->close = clean->close;
+		break;
+	case Dread:
+		d->read = clean->read;
+		break;
+	case Dbread:
+		d->bread = clean->bread;
+		break;
+	case Dwrite:
+		d->write = clean->write;
+		break;
+	case Dbwrite:
+		d->bwrite = clean->bwrite;
+		break;
+	case Dremove:
+		d->remove = clean->remove;
+		break;
+	case Dwstat:
+		d->wstat = clean->wstat;
+		break;
+	}
+}
+
+DTProvider dtracydevprov = {
+	.name = "dev",
+	.provide = devprovide,
+	.enable = devenable,
+	.disable = devdisable,
+};
--- a//sys/src/9/port/portmkfile
+++ b//sys/src/9/port/portmkfile
@@ -88,7 +88,7 @@
 netif.$O:	../port/netif.h
 devuart.$O:	../port/netif.h
 devbridge.$O:	../port/netif.h ../ip/ip.h ../ip/ipv6.h
-devdtracy.$O dtracysys.$O dtracytimer.$O:	/sys/include/dtracy.h
+devdtracy.$O dtracysys.$O dtracytimer.$O dtracydev.$O:	/sys/include/dtracy.h
 devdraw.$O:	screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/memlayer.h /sys/include/cursor.h
 devmouse.$O:	screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
 swcursor.$O:	screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h

                 reply	other threads:[~2022-06-12  5:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=041b6f71-14f3-b478-4981-7d08d762d20e@posixcafe.org \
    --to=moody@mail.posixcafe.org \
    --cc=9front@9front.org \
    --subject='Re: [9front] [PATCH] teach dtracy how to drive' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).