Linux DTrace development list
 help / color / mirror / Atom feed
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
>>
>>
>>


  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