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).