[DTrace-devel] [PATCH v3 10/11] htab reduction: modules
Nick Alcock
nick.alcock at oracle.com
Mon Nov 1 14:29:46 UTC 2021
This one is nice and simple, just the same as all the others.
We can ditch nmods in favour of dt_htab_entries, but cannot remove the
modlist (because the order of modules matters, so htab iteration cannot
replace it).
Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
libdtrace/dt_impl.h | 8 ++--
libdtrace/dt_module.c | 102 +++++++++++++++++++++++++-----------------
libdtrace/dt_module.h | 3 +-
libdtrace/dt_open.c | 14 ++----
4 files changed, 69 insertions(+), 58 deletions(-)
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index 615cf0964834..91953273b87a 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -113,7 +113,9 @@ typedef struct dt_module {
char dm_name[DTRACE_MODNAMELEN]; /* string name of module */
char dm_file[PATH_MAX]; /* file path of module */
uint_t dm_flags; /* module flags (see below) */
- struct dt_module *dm_next; /* pointer to next module in hash chain */
+ struct dt_hentry dm_he; /* htab links */
+ dtrace_hdl_t *dm_dtp; /* backpointer to the dtrace instance */
+
dtrace_addr_range_t *dm_text_addrs; /* text addresses, sorted */
size_t dm_text_addrs_size; /* number of entries */
@@ -294,9 +296,7 @@ struct dtrace_hdl {
uint_t dt_maxlvaralloc; /* largest lvar alloc across pcbs */
dt_tstring_t *dt_tstrings; /* temporary string slots */
dt_list_t dt_modlist; /* linked list of dt_module_t's */
- dt_module_t **dt_mods; /* hash table of dt_module_t's */
- uint_t dt_modbuckets; /* number of module hash buckets */
- uint_t dt_nmods; /* number of modules in hash and list */
+ dt_htab_t *dt_mods; /* hash table of dt_module_t's */
ctf_archive_t *dt_ctfa; /* ctf archive for the entire kernel tree */
ctf_file_t *dt_shared_ctf; /* Handle to the shared CTF */
char *dt_ctfa_path; /* path to vmlinux.ctfa */
diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index 60088fe3ffd6..5891e2a714cb 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -40,6 +40,40 @@ dt_module_shuffle_to_start(dtrace_hdl_t *dtp, const char *name);
static void
dt_kern_module_find_ctf(dtrace_hdl_t *dtp, dt_module_t *dmp);
+static uint32_t
+dt_module_hval(const dt_module_t *mod)
+{
+ return str2hval(mod->dm_name, 0);
+}
+
+static int
+dt_module_cmp(const dt_module_t *p, const dt_module_t *q)
+{
+ return strcmp(p->dm_name, q->dm_name);
+}
+
+DEFINE_HE_STD_LINK_FUNCS(dt_module, dt_module_t, dm_he)
+
+static void *
+dt_module_del_mod(dt_module_t *head, dt_module_t *dmp)
+{
+ head = dt_module_del(head, dmp);
+ dt_list_delete(&dmp->dm_dtp->dt_modlist, dmp);
+
+ dt_module_unload(dmp->dm_dtp, dmp);
+ free(dmp);
+
+ return head;
+}
+
+static dt_htab_ops_t dt_module_htab_ops = {
+ .hval = (htab_hval_fn)dt_module_hval,
+ .cmp = (htab_cmp_fn)dt_module_cmp,
+ .add = (htab_add_fn)dt_module_add,
+ .next = (htab_next_fn)dt_module_next,
+ .del = (htab_del_fn)dt_module_del_mod
+};
+
/*
* Symbol table management for userspace modules, via ELF parsing.
*/
@@ -96,27 +130,33 @@ dt_module_symgelf64(const Elf64_Sym *src, GElf_Sym *dst)
dt_module_t *
dt_module_create(dtrace_hdl_t *dtp, const char *name)
{
- uint_t h = str2hval(name, 0) % dtp->dt_modbuckets;
dt_module_t *dmp;
- for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next)
- if (strcmp(dmp->dm_name, name) == 0)
- return dmp;
+ if (!dtp->dt_mods) {
+ dtp->dt_mods = dt_htab_create(dtp, &dt_module_htab_ops);
+ if (!dtp->dt_mods)
+ return NULL;
+ }
+
+ if ((dmp = dt_module_lookup_by_name(dtp, name)) != NULL)
+ return dmp;
if ((dmp = malloc(sizeof(dt_module_t))) == NULL)
return NULL; /* caller must handle allocation failure */
memset(dmp, 0, sizeof(dt_module_t));
strlcpy(dmp->dm_name, name, sizeof(dmp->dm_name));
+ if (dt_htab_insert(dtp->dt_mods, dmp) < 0) {
+ free(dmp);
+ return NULL;
+ }
dt_list_append(&dtp->dt_modlist, dmp);
- dmp->dm_next = dtp->dt_mods[h];
- dtp->dt_mods[h] = dmp;
- dtp->dt_nmods++;
if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)
dmp->dm_ops = &dt_modops_64;
else
dmp->dm_ops = &dt_modops_32;
+ dmp->dm_dtp = dtp;
return dmp;
}
@@ -124,8 +164,13 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name)
dt_module_t *
dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
{
- uint_t h = str2hval(name, 0) % dtp->dt_modbuckets;
- dt_module_t *dmp;
+ dt_module_t tmpl;
+
+ if (strlen(name) > (DTRACE_MODNAMELEN - 1))
+ return NULL;
+
+ if (!dtp->dt_mods)
+ return NULL; /* no modules yet */
/* 'genunix' is an alias for 'vmlinux'. */
@@ -133,11 +178,8 @@ dt_module_lookup_by_name(dtrace_hdl_t *dtp, const char *name)
name = "vmlinux";
}
- for (dmp = dtp->dt_mods[h]; dmp != NULL; dmp = dmp->dm_next)
- if (strcmp(dmp->dm_name, name) == 0)
- return dmp;
-
- return NULL;
+ strcpy(tmpl.dm_name, name);
+ return dt_htab_lookup(dtp->dt_mods, &tmpl);
}
/*ARGSUSED*/
@@ -179,7 +221,7 @@ dt_module_init_elf(dtrace_hdl_t *dtp, dt_module_t *dmp)
elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) {
dt_dprintf("failed to load %s: %s\n", dmp->dm_file,
elf_errmsg(elf_errno()));
- dt_module_destroy(dtp, dmp);
+ dt_htab_delete(dtp->dt_mods, dmp);
return dt_set_errno(dtp, EDT_OBJIO);
}
@@ -195,7 +237,7 @@ dt_module_init_elf(dtrace_hdl_t *dtp, dt_module_t *dmp)
default:
dt_dprintf("failed to load %s: unknown ELF class\n",
dmp->dm_file);
- dt_module_destroy(dtp, dmp);
+ dt_htab_delete(dtp->dt_mods, dmp);
return dt_set_errno(dtp, EDT_ELFCLASS);
}
@@ -609,30 +651,6 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp)
dmp->dm_flags &= ~DT_DM_LOADED;
}
-void
-dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp)
-{
- uint_t h = str2hval(dmp->dm_name, 0) % dtp->dt_modbuckets;
- dt_module_t *scan_dmp;
- dt_module_t *prev_dmp = NULL;
-
- dt_list_delete(&dtp->dt_modlist, dmp);
- assert(dtp->dt_nmods != 0);
- dtp->dt_nmods--;
-
- for (scan_dmp = dtp->dt_mods[h]; (scan_dmp != NULL) && (scan_dmp != dmp);
- scan_dmp = scan_dmp->dm_next) {
- prev_dmp = scan_dmp;
- }
- if (prev_dmp == NULL)
- dtp->dt_mods[h] = dmp->dm_next;
- else
- prev_dmp->dm_next = dmp->dm_next;
-
- dt_module_unload(dtp, dmp);
- free(dmp);
-}
-
/*
* Insert a new external symbol reference into the specified module. The new
* symbol will be marked as undefined and is assigned a symbol index beyond
@@ -1360,7 +1378,7 @@ dtrace_lookup_by_name(dtrace_hdl_t *dtp, const char *object, const char *name,
mask = DT_DM_KERNEL;
dmp = dt_list_next(&dtp->dt_modlist);
- n = dtp->dt_nmods;
+ n = dt_htab_entries(dtp->dt_mods);
}
if (symp == NULL)
@@ -1562,7 +1580,7 @@ dtrace_lookup_by_type(dtrace_hdl_t *dtp, const char *object, const char *name,
mask = DT_DM_KERNEL;
dmp = dt_list_next(&dtp->dt_modlist);
- n = dtp->dt_nmods;
+ n = dt_htab_entries(dtp->dt_mods);
justone = 0;
}
diff --git a/libdtrace/dt_module.h b/libdtrace/dt_module.h
index b5f2fc247690..56df17a622f4 100644
--- a/libdtrace/dt_module.h
+++ b/libdtrace/dt_module.h
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
@@ -15,7 +15,6 @@ extern "C" {
#endif
extern dt_module_t *dt_module_create(dtrace_hdl_t *, const char *);
-extern void dt_module_destroy(dtrace_hdl_t *, dt_module_t *);
extern dt_module_t *dt_module_lookup_by_name(dtrace_hdl_t *, const char *);
extern dt_module_t *dt_module_lookup_by_ctf(dtrace_hdl_t *, ctf_file_t *);
diff --git a/libdtrace/dt_open.c b/libdtrace/dt_open.c
index c145c1041454..9a31fe5bf894 100644
--- a/libdtrace/dt_open.c
+++ b/libdtrace/dt_open.c
@@ -734,8 +734,6 @@ dt_vopen(int version, int flags, int *errp,
dtp->dt_ddefs_fd = -1;
dtp->dt_stdout_fd = -1;
dtp->dt_poll_fd = -1;
- dtp->dt_modbuckets = _dtrace_strbuckets;
- dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof(dt_module_t *));
dt_proc_hash_create(dtp);
dtp->dt_proc_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
dtp->dt_nextepid = 1;
@@ -768,9 +766,9 @@ dt_vopen(int version, int flags, int *errp,
if (dt_str2kver(dtp->dt_uts.release, &dtp->dt_kernver) < 0)
return set_open_errno(dtp, errp, EDT_VERSINVAL);
- if (dtp->dt_mods == NULL || dtp->dt_procs == NULL ||
- dtp->dt_ld_path == NULL || dtp->dt_cpp_path == NULL ||
- dtp->dt_cpp_argv == NULL || dtp->dt_sysslice == NULL)
+ if (dtp->dt_procs == NULL || dtp->dt_ld_path == NULL ||
+ dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL ||
+ dtp->dt_sysslice == NULL)
return set_open_errno(dtp, errp, EDT_NOMEM);
for (i = 0; i < DTRACEOPT_MAX; i++)
@@ -1179,7 +1177,6 @@ void
dtrace_close(dtrace_hdl_t *dtp)
{
dt_ident_t *idp, *ndp;
- dt_module_t *dmp;
dtrace_prog_t *pgp;
dt_xlator_t *dxp;
dt_dirpath_t *dirp;
@@ -1223,9 +1220,7 @@ dtrace_close(dtrace_hdl_t *dtp)
if (dtp->dt_bpfsyms != NULL)
dt_idhash_destroy(dtp->dt_bpfsyms);
- while ((dmp = dt_list_next(&dtp->dt_modlist)) != NULL)
- dt_module_destroy(dtp, dmp);
-
+ dt_htab_destroy(dtp, dtp->dt_mods);
dt_htab_destroy(dtp, dtp->dt_kernpaths);
if (dtp->dt_shared_ctf != NULL)
@@ -1275,7 +1270,6 @@ dtrace_close(dtrace_hdl_t *dtp)
free(dtp->dt_sprintf_buf);
pthread_mutex_destroy(&dtp->dt_sprintf_lock);
- free(dtp->dt_mods);
free(dtp->dt_module_path);
free(dtp->dt_strtab);
free(dtp);
--
2.33.1.257.g9e0974a4e8
More information about the DTrace-devel
mailing list