From f2edb5e306aaa3776b3bbbc21095f547ee648309 Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Wed, 7 Aug 2013 16:09:27 -0400 Subject: [PATCH] Bug fix for fasttrap module unloading. Various scenarios have been uncovered where unloading of the fasttrap module would result in an assertion failure. Essentially, what is going on is that an executable may register providers for USDT probes (i.e. pass a DOF object to DTrace through the helper interface) while there isn't any consumer active. Any attempt to remove the fasttrap provider at this point in time causes an assertion failure on the reference count for all providers instantiated by the the meta-provider (fasttrap), because module removal cannot be stopped once it has been initiated. The solution is to take a reference on the meta-provider module whenever a new provider is instantiated in it, and to put the reference back when that provider is retired (removed from use). I.e. the module will be listed as in use as long as there are providers associated with it. Signed-off-by: Kris Van Hees --- dtrace/fasttrap_dev.c | 5 ++++- dtrace/include/dtrace/provider.h | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dtrace/fasttrap_dev.c b/dtrace/fasttrap_dev.c index b419e55a250b..e5a1d4271dd4 100644 --- a/dtrace/fasttrap_dev.c +++ b/dtrace/fasttrap_dev.c @@ -705,7 +705,6 @@ static void fasttrap_pid_getargdesc(void *arg, dtrace_id_t id, void *parg, static uint64_t fasttrap_usdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes) { -pr_info("FASTTRAP: fasttrap_usdt_getarg(%p, %d, %p, %d, %d) called\n", arg, id, parg, argno, aframes); return 0; /* FIXME */ } @@ -1196,6 +1195,8 @@ void *fasttrap_meta_provide(void *arg, dtrace_helper_provdesc_t *dhpv, mutex_unlock(&provider->ftp_mtx); + __module_get(THIS_MODULE); + return provider; } @@ -1283,6 +1284,8 @@ static void fasttrap_pid_cleanup_cb(struct work_struct *work) } else { *fpp = fp->ftp_next; fasttrap_provider_free(fp); + + module_put(THIS_MODULE); } } diff --git a/dtrace/include/dtrace/provider.h b/dtrace/include/dtrace/provider.h index d3653255dd95..6bc7c6b559ae 100644 --- a/dtrace/include/dtrace/provider.h +++ b/dtrace/include/dtrace/provider.h @@ -919,7 +919,7 @@ extern void dtrace_probe(dtrace_id_t, uintptr_t, uintptr_t, uintptr_t, prov->dtmp_priv, NULL, \ prov->dtmp_pops, prov, \ &prov->dtmp_id) != 0) \ - pr_warning("Failed to register sdt provider %s",\ + pr_warning("Failed to register provider %s", \ prov->dtmp_name); \ } \ \ @@ -938,7 +938,7 @@ extern void dtrace_probe(dtrace_id_t, uintptr_t, uintptr_t, uintptr_t, if (prov->dtmp_id != DTRACE_PROVNONE) { \ ret = dtrace_unregister(prov->dtmp_id); \ if (ret != 0) \ - pr_warning("Failed to unregister sdt " \ + pr_warning("Failed to unregister " \ "provider %s: %d", \ prov->dtmp_name, ret); \ \ -- 2.50.1