From: Kris Van Hees <kris.van.hees@oracle.com>
To: dtrace@lists.linux.dev, dtrace-devel@oss.oracle.com
Subject: [PATCH 10/20] libdtrace: retain descriptors for cached module BTF IDs
Date: Fri, 30 Oct 2026 19:36:45 +0000 [thread overview]
Message-ID: <56247e0c69f34acca1cc8c20ffafc4bd@oracle.com> (raw)
---
libdtrace/dt_btf.c | 79 ++++++++++++++++++++++++++++++--
libdtrace/dt_impl.h | 1 +
libdtrace/dt_open.c | 1 +
test/triggers/module-discovery.c | 11 +++++
4 files changed, 88 insertions(+), 4 deletions(-)
diff --git a/libdtrace/dt_btf.c b/libdtrace/dt_btf.c
index 617b0128..727e5f54 100644
--- a/libdtrace/dt_btf.c
+++ b/libdtrace/dt_btf.c
@@ -1479,17 +1479,67 @@ dt_btf_lookup_name_kind(dtrace_hdl_t *dtp, dt_module_t *dmp, const char *name,
return id;
}
+/*
+ * Retain a descriptor as well as the ID: otherwise an unloaded object's ID
+ * could be reused and a later enumeration could mistake it for a cached one.
+ * Only IDs assigned to modules are retained, bounding descriptor use by the
+ * number of modules discovered by this handle.
+ */
+typedef struct dt_btf_id {
+ dt_hentry_t he;
+ uint32_t id;
+ int fd;
+} dt_btf_id_t;
+
+static uint32_t
+dt_btf_id_hval(const dt_btf_id_t *entry)
+{
+ return entry->id;
+}
+
+static int
+dt_btf_id_cmp(const dt_btf_id_t *a, const dt_btf_id_t *b)
+{
+ return a->id != b->id;
+}
+
+DEFINE_HE_STD_LINK_FUNCS(dt_btf_id, dt_btf_id_t, he)
+
+static void *
+dt_btf_id_release(dt_btf_id_t *head, dt_btf_id_t *entry)
+{
+ head = dt_btf_id_del(head, entry);
+ close(entry->fd);
+ free(entry);
+ return head;
+}
+
+static dt_htab_ops_t dt_btf_id_ops = {
+ .hval = (htab_hval_fn)dt_btf_id_hval,
+ .cmp = (htab_cmp_fn)dt_btf_id_cmp,
+ .add = (htab_add_fn)dt_btf_id_add,
+ .del = (htab_del_fn)dt_btf_id_release,
+ .next = (htab_next_fn)dt_btf_id_next
+};
+
int
dt_btf_get_module_ids(dtrace_hdl_t *dtp)
{
uint32_t id = 0;
+ if (dtp->dt_btf_ids == NULL) {
+ dtp->dt_btf_ids = dt_htab_create(&dt_btf_id_ops);
+ if (dtp->dt_btf_ids == NULL)
+ return dt_set_errno(dtp, EDT_NOMEM);
+ }
+
for (;;) {
int rc, fd;
btf_info_t info;
char name[PATH_MAX];
uint32_t size = sizeof(info);
dt_module_t *dmp;
+ dt_btf_id_t tmpl, *entry;
rc = dt_bpf_btf_get_next_id(id, &id);
if (rc) {
@@ -1501,6 +1551,10 @@ dt_btf_get_module_ids(dtrace_hdl_t *dtp)
return dt_set_errno(dtp, errno);
}
+ tmpl.id = id;
+ if (dt_htab_lookup(dtp->dt_btf_ids, &tmpl) != NULL)
+ continue;
+
fd = dt_bpf_btf_get_fd_by_id(id);
if (fd < 0) {
if (errno == ENOENT)
@@ -1513,14 +1567,31 @@ dt_btf_get_module_ids(dtrace_hdl_t *dtp)
info.name = (uint64_t)name;
info.name_len = sizeof(name);
rc = dt_bpf_btf_get_info_by_fd(fd, &info, &size);
- close(fd);
- if (rc)
- return dt_set_errno(dtp, errno);
+ if (rc) {
+ int err = errno;
+
+ close(fd);
+ return dt_set_errno(dtp, err);
+ }
dmp = dt_module_lookup_by_name(dtp, name);
- if (dmp == NULL || dmp->dm_btf_id != 0)
+ if (!info.kernel_btf || dmp == NULL || dmp->dm_btf_id != 0) {
+ close(fd);
continue;
+ }
+ entry = calloc(1, sizeof(*entry));
+ if (entry == NULL) {
+ close(fd);
+ return dt_set_errno(dtp, EDT_NOMEM);
+ }
+ entry->id = id;
+ entry->fd = fd;
+ if (dt_htab_insert(dtp->dt_btf_ids, entry) != 0) {
+ close(fd);
+ free(entry);
+ return dt_set_errno(dtp, EDT_NOMEM);
+ }
dmp->dm_btf_id = id;
}
}
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index f89ce2bc..972fceaf 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -314,6 +314,7 @@ struct dtrace_hdl {
ctf_archive_t *dt_ctfa; /* ctf archive for the entire kernel tree */
void *dt_ctfa_data; /* backing data for dt_ctfa */
char *dt_btf_path; /* path to vmlinux.btf */
+ dt_htab_t *dt_btf_ids; /* retained module BTF IDs and descriptors */
dt_htab_t *dt_kernpaths; /* hash table of dt_kern_path_t's */
dt_module_t *dt_exec; /* pointer to executable module */
dt_module_t *dt_cdefs; /* pointer to C dynamic type module */
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index 245ccb70..8291b87d 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -1313,6 +1313,7 @@ dtrace_close(dtrace_hdl_t *dtp)
dtp->dt_kernsyms = NULL;
dt_htab_destroy(dtp->dt_mods);
dt_htab_destroy(dtp->dt_kernpaths);
+ dt_htab_destroy(dtp->dt_btf_ids);
if (dtp->dt_ctfa != NULL)
ctf_arc_close(dtp->dt_ctfa);
diff --git a/test/triggers/module-discovery.c b/test/triggers/module-discovery.c
index 0b09ae2b..d05d2bab 100644
--- a/test/triggers/module-discovery.c
+++ b/test/triggers/module-discovery.c
@@ -22,6 +22,7 @@
static const char *symbols;
static int kallsyms;
static uint32_t btf_generation, btf_id;
+static int btf_queries;
extern FILE *__real_fopen64(const char *, const char *);
@@ -78,6 +79,8 @@ __wrap_dt_bpf_btf_get_info_by_fd(int fd, btf_info_t *info, uint32_t *size)
if (symbols == NULL)
return __real_dt_bpf_btf_get_info_by_fd(fd, info, size);
+ btf_queries++;
+ info->kernel_btf = 1;
snprintf((char *)(uintptr_t)info->name, info->name_len, "%s",
names[btf_id - btf_generation - 1]);
return 0;
@@ -171,6 +174,14 @@ check_discovery(int fallback)
}
CHECK(count == 2 && found_first == 1 && found_second == 1);
+ /* Cached IDs are pinned; enumeration only queries unassigned reload IDs. */
+ btf_queries = 0;
+ CHECK(dtrace_update(dtp) == 0);
+ CHECK(btf_queries == 2);
+ btf_queries = 0;
+ CHECK(dtrace_update(dtp) == 0);
+ CHECK(btf_queries == 2);
+
/* Disappearance and reappearance at a new address do not replace metadata. */
for (i = 0; i < 4; i++) {
symbols = i % 2 == 0 ? "" : fallback ?
--
2.52.0
reply other threads:[~2026-10-30 19:38 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=56247e0c69f34acca1cc8c20ffafc4bd@oracle.com \
--to=kris.van.hees@oracle.com \
--cc=dtrace-devel@oss.oracle.com \
--cc=dtrace@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.