From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 8923 invoked from network); 12 Jun 2022 05:48:47 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 12 Jun 2022 05:48:47 -0000 Received: from mail.posixcafe.org ([45.76.19.58]) by 9front; Sun Jun 12 01:47:07 -0400 2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posixcafe.org; s=20200506; t=1655012823; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=kg2JDdmhZ6ZUm16QQEbnRMFwWNSNKTwnbDImK1CV3HM=; b=in6tUk+TclUnCqnsGPAv/LLPKnRoXfFhDMi/IzXKXlhmXcH2OYua2mpkoq3d7r1C39g0uK 5ZiMri/SLnQ/RrVknhLxi7mWCEQSoC4RehP04JFYgwQ1R4SvTRb7v0FNHzR5t5t3kOvoF0 g/8ArF+kzgAuzcYseDoNznfpizx3Y9I= Received: from [192.168.168.200] (161-97-228-135.lpcnextlight.net [161.97.228.135]) by mail.posixcafe.org (OpenSMTPD) with ESMTPSA id 54678692 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for <9front@9front.org>; Sun, 12 Jun 2022 00:47:03 -0500 (CDT) Message-ID: <041b6f71-14f3-b478-4981-7d08d762d20e@posixcafe.org> Date: Sat, 11 Jun 2022 23:46:20 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1 Content-Language: en-US To: 9front@9front.org From: Jacob Moody Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: mobile webscale database core lifecycle-oriented database layer Subject: [9front] [PATCH] teach dtracy how to drive Reply-To: 9front@9front.org Precedence: bulk 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 + +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