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 \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).