]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Bug fix for fasttrap module unloading.
authorKris Van Hees <kris.van.hees@oracle.com>
Wed, 7 Aug 2013 20:09:27 +0000 (16:09 -0400)
committerNick Alcock <nick.alcock@oracle.com>
Thu, 8 Aug 2013 10:36:12 +0000 (11:36 +0100)
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 <kris.van.hees@oracle.com>
dtrace/fasttrap_dev.c
dtrace/include/dtrace/provider.h

index b419e55a250b6726f296816d7dd0ea9bb4f1f0f8..e5a1d4271dd428b6eecbf13092e59ae7ac408448 100644 (file)
@@ -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);
                                }
                        }
 
index d3653255dd9500a6d983b8c5d2878526725032f7..6bc7c6b559aed696f94b8955801ea7ae0fcb4c9b 100644 (file)
@@ -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);       \
                                                                        \