From: Alan Maguire <alan.maguire@oracle.com>
To: Kris Van Hees <kris.van.hees@oracle.com>
Cc: dtrace@lists.linux.dev, dtrace-devel@oss.oracle.com
Subject: Re: [PATCH v3 2/7] libdtrace: share vmlinux BTF/CTF globally to support faster startup
Date: Thu, 23 Jul 2026 14:22:10 +0100 [thread overview]
Message-ID: <bfb1980c-c27e-40c2-b60c-025d2159df61@oracle.com> (raw)
In-Reply-To: <amE0WSxviiSt9OKR@oracle.com>
On 22/07/2026 22:21, Kris Van Hees wrote:
> On Tue, Jul 21, 2026 at 04:24:46PM +0100, Alan Maguire wrote:
>> In a multiple DTrace session per process environment, it makes sense
>> to avoid doing expensive operations like reading in vmlinux BTF and
>> converting it to CTF more than once. Shared (vmlinux) BTF and CTF
>> generated from it are shared and reference-counted globally here
>> to cut down on cost. With this change, we can launch ~1 DTrace
>> session per second.
>
> There are a few logic issues here that need to be address I think. Since we
> do support -xbtfpath and DTRACE_OPT_BTFPATH, hardcoding the path to vmlinux
> is an issue.
>
> Ideally, this code should allow for both shared and private type data. I.e.
> if a -xbtfpath opion is given or DTRACE_OPT_BTFPATH is set, then the instance
> will use a private copy. Otherwise, it will use a shared one that is sourced
> from the system default.
>
> More fancy would be to allow multiple shared ones, keyed by full path (and
> considering that it will be very very rare to ever have more than one).
>
> So, I would suggest going with the first option (shared and private), and the
> close code can check whether dtp->dt_shared_btf == dt_shared_btf. If so, it
> is a hared one so handle it that way. If not, clean up as a private copy.
>
good catch, thanks! I'll do this in the next version.
>> Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
>> ---
>> libdtrace/dt_btf.c | 61 ++++++++++++++++++++++++++++++++++++++++++---
>> libdtrace/dt_btf.h | 1 +
>> libdtrace/dt_open.c | 5 +---
>> 3 files changed, 60 insertions(+), 7 deletions(-)
>>
>> diff --git a/libdtrace/dt_btf.c b/libdtrace/dt_btf.c
>> index 1f793397..e46336f9 100644
>> --- a/libdtrace/dt_btf.c
>> +++ b/libdtrace/dt_btf.c
>> @@ -693,6 +693,9 @@ dt_btf_to_ctf(dtrace_hdl_t *dtp, dt_module_t *dmp, dt_btf_t *btf)
>> ctf_dict_t *ctf;
>> ctf_encoding_t enc = { CTF_INT_SIGNED, 0, 0 };
>>
>> + if (dmp == NULL && dtp->dt_shared_ctf)
>> + return dtp->dt_shared_ctf;
>> +
>> ctf = ctf_create(&dtp->dt_ctferr);
>> if (ctf == NULL)
>> return NULL;
>> @@ -764,6 +767,56 @@ out:
>> }
>> #endif
>>
>> +static dt_btf_t *dt_shared_btf = NULL;
>> +static ctf_dict_t *dt_shared_ctf = NULL;
>> +static pthread_mutex_t dt_shared_mutex = PTHREAD_MUTEX_INITIALIZER;
>> +static int dt_shared_refcnt = 0;
>> +
>> +static int
>> +dt_shared_get(dtrace_hdl_t *dtp, dt_module_t *dmp)
>> +{
>> + pthread_mutex_lock(&dt_shared_mutex);
>> + if (!dt_shared_btf)
>> + dt_shared_btf = dt_btf_load_file(dtp, "/sys/kernel/btf/vmlinux");
>> + if (dt_shared_btf) {
>> + dt_shared_refcnt++;
>> + dtp->dt_shared_btf = dmp->dm_btf = dt_shared_btf;
>> +#ifdef HAVE_LIBCTF
>> + if (!dt_shared_ctf) {
>> + ctf_dict_t *ctf = dt_btf_to_ctf(dtp, NULL, dt_shared_btf);
>> +
>> + if (ctf)
>> + dtp->dt_shared_ctf = dt_shared_ctf = dmp->dm_ctfp = ctf;
>> + } else {
>> + dtp->dt_shared_ctf = dmp->dm_ctfp = dt_shared_ctf;
>> + }
>> +#endif
>> + }
>> + pthread_mutex_unlock(&dt_shared_mutex);
>> + if (!dt_shared_btf)
>> + return -1;
>> + return 0;
>> +}
>> +
>> +void
>> +dt_shared_put(dtrace_hdl_t *dtp)
>> +{
>> + pthread_mutex_lock(&dt_shared_mutex);
>> + if (dtp->dt_shared_btf && dtp->dt_shared_btf == dt_shared_btf) {
>> + if (--dt_shared_refcnt == 0) {
>> + dt_btf_destroy(dtp, dtp->dt_shared_btf);
>> + dtp->dt_shared_btf = dt_shared_btf = NULL;
>> + }
>> + }
>> +#ifdef HAVE_LIBCTF
>> + if (dt_shared_refcnt == 0) {
>> + ctf_close(dtp->dt_shared_ctf);
>> + dtp->dt_shared_ctf = dt_shared_ctf = NULL;
>> + }
>> +#endif
>> + pthread_mutex_unlock(&dt_shared_mutex);
>> +}
>> +
>> dt_btf_t *
>> dt_btf_load_module(dtrace_hdl_t *dtp, dt_module_t *dmp)
>> {
>> @@ -774,6 +827,11 @@ dt_btf_load_module(dtrace_hdl_t *dtp, dt_module_t *dmp)
>> if (dmp->dm_btf)
>> return dmp->dm_btf;
>>
>> + if (strcmp(dmp->dm_name, "vmlinux") == 0) {
>> + if (dt_shared_get(dtp, dmp) == 0)
>> + return dmp->dm_btf;
>> + }
>> +
>> /*
>> * Default: /sys/kernel/btf/<module>
>> * If "none", disable BTF.
>> @@ -792,9 +850,6 @@ dt_btf_load_module(dtrace_hdl_t *dtp, dt_module_t *dmp)
>> btf = dt_btf_load_file(dtp, fn);
>> free(fn);
>>
>> - if (btf && !dtp->dt_shared_btf && strcmp(dmp->dm_name, "vmlinux") == 0)
>> - dtp->dt_shared_btf = btf;
>> -
>> return dmp->dm_btf = btf;
>> }
>>
>> diff --git a/libdtrace/dt_btf.h b/libdtrace/dt_btf.h
>> index 2c921a03..b1ed2b65 100644
>> --- a/libdtrace/dt_btf.h
>> +++ b/libdtrace/dt_btf.h
>> @@ -18,6 +18,7 @@ typedef struct dt_btf dt_btf_t;
>> typedef struct bpf_btf_info btf_info_t;
>>
>> extern void dt_btf_destroy(dtrace_hdl_t *, dt_btf_t *);
>> +extern void dt_shared_put(dtrace_hdl_t *);
>> extern dt_btf_t *dt_btf_load_module(dtrace_hdl_t *, dt_module_t *);
>> extern ctf_dict_t *dt_btf_module_ctf(dtrace_hdl_t *, dt_module_t *);
>> extern const char *dt_btf_get_string(dtrace_hdl_t *, const dt_btf_t *,
>> diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
>> index 30b8758d..352cec49 100644
>> --- a/libdtrace/dt_open.c
>> +++ b/libdtrace/dt_open.c
>> @@ -1299,10 +1299,7 @@ dtrace_close(dtrace_hdl_t *dtp)
>> dt_htab_destroy(dtp->dt_mods);
>> dt_htab_destroy(dtp->dt_kernpaths);
>>
>> - if (dtp->dt_shared_btf != NULL)
>> - dt_btf_destroy(dtp, dtp->dt_shared_btf);
>> - if (dtp->dt_shared_ctf != NULL)
>> - ctf_close(dtp->dt_shared_ctf);
>> + dt_shared_put(dtp);
>> if (dtp->dt_ctfa != NULL)
>> ctf_arc_close(dtp->dt_ctfa);
>>
>> --
>> 2.43.5
>>
>>
>>
next prev parent reply other threads:[~2026-07-23 13:22 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 15:24 [PATCH v3 0/7] Add python bindings for libdtrace interfaces Alan Maguire
2026-07-21 15:24 ` [PATCH v3 1/7] libdtrace: Support multiple DTrace handles per process Alan Maguire
2026-07-22 21:09 ` Kris Van Hees
2026-07-23 12:33 ` Alan Maguire
2026-07-21 15:24 ` [PATCH v3 2/7] libdtrace: share vmlinux BTF/CTF globally to support faster startup Alan Maguire
2026-07-22 21:21 ` Kris Van Hees
2026-07-23 13:22 ` Alan Maguire [this message]
2026-07-21 15:24 ` [PATCH v3 3/7] libdtrace: Refactor math functions into dt_math.h Alan Maguire
2026-07-21 15:24 ` [PATCH v3 4/7] python: Add cpython bindings for libdtrace Alan Maguire
2026-07-21 15:24 ` [PATCH v3 5/7] dtrace.spec: add python bindings packaging Alan Maguire
2026-07-21 15:24 ` [PATCH v3 6/7] runtest.sh: Export PYTHONPATH when running tests in-tree Alan Maguire
2026-07-21 15:24 ` [PATCH v3 7/7] test: add tests for python bindings Alan Maguire
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=bfb1980c-c27e-40c2-b60c-025d2159df61@oracle.com \
--to=alan.maguire@oracle.com \
--cc=dtrace-devel@oss.oracle.com \
--cc=dtrace@lists.linux.dev \
--cc=kris.van.hees@oracle.com \
/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