[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