]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Implement refcount handling in DTrace modules to ensure that they cannot be
authorKris Van Hees <kris.van.hees@oracle.com>
Tue, 14 Feb 2012 21:22:33 +0000 (16:22 -0500)
committerKris Van Hees <kris.van.hees@oracle.com>
Tue, 14 Feb 2012 21:22:33 +0000 (16:22 -0500)
unloaded while probes are enabled.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
13 files changed:
dtrace/dt_test.h
dtrace/dt_test_dev.c
dtrace/dt_test_mod.c
dtrace/dtrace.h
dtrace/profile.h
dtrace/profile_dev.c
dtrace/profile_mod.c
dtrace/sdt_dev.c
dtrace/sdt_impl.h
dtrace/sdt_mod.c
dtrace/systrace.h
dtrace/systrace_dev.c
dtrace/systrace_mod.c

index 7ce73d10e8a0fe398894c925cdd8f1ee66da9f62..d7d980296ac515a165dc7fbbcdf5d6a1c67a5514 100644 (file)
@@ -28,8 +28,8 @@
 #define _DT_TEST_H_
 
 extern void dt_test_provide(void *, const dtrace_probedesc_t *);
-extern int dt_test_enable(void *arg, dtrace_id_t, void *);
-extern void dt_test_disable(void *arg, dtrace_id_t, void *);
+extern int _dt_test_enable(void *arg, dtrace_id_t, void *);
+extern void _dt_test_disable(void *arg, dtrace_id_t, void *);
 extern void dt_test_destroy(void *, dtrace_id_t, void *);
 
 extern dtrace_provider_id_t    dt_test_id;
index 7af3b5c08560db613331386042326a0c1ecad488..edcdac203a5e81a10a819fee869e6ba16f7c43af 100644 (file)
@@ -46,14 +46,14 @@ void dt_test_provide(void *arg, const dtrace_probedesc_t *desc)
                                  "dt_test", NULL, "test", 0, NULL);
 }
 
-int dt_test_enable(void *arg, dtrace_id_t id, void *parg)
+int _dt_test_enable(void *arg, dtrace_id_t id, void *parg)
 {
        enabled = 1;
 
        return 0;
 }
 
-void dt_test_disable(void *arg, dtrace_id_t id, void *parg)
+void _dt_test_disable(void *arg, dtrace_id_t id, void *parg)
 {
        enabled = 0;
 }
index 4ad3d7b493d2e72a4bda1ddf1d57b881d5a14d72..fb2c27b6b886cb211790798599b3b105e60cff64 100644 (file)
@@ -44,6 +44,8 @@ static const dtrace_pattr_t dt_test_attr = {
 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
 };
 
+DT_PROVIDER_POPS(dt_test)
+
 static dtrace_pops_t dt_test_pops = {
        dt_test_provide,
        NULL,
@@ -57,4 +59,4 @@ static dtrace_pops_t dt_test_pops = {
        dt_test_destroy
 };
 
-DT_PROVIDER_MODULE(dt_test, DTRACE_PRIV_USER);
+DT_PROVIDER_MODULE(dt_test, DTRACE_PRIV_USER)
index 53b444b43a74366ca5dfdb07d9656bcfb393c69f..ff054d294da721fd4129bbab7f9e8bc2859352ea 100644 (file)
@@ -2135,8 +2135,36 @@ extern int dtrace_badattr(const dtrace_attribute_t *);
 extern int dtrace_badname(const char *);
 extern void dtrace_cred2priv(const cred_t *, uint32_t *, uid_t *);
 
+#define DT_PROVIDER_POPS(name)                                         \
+  static unsigned int  name##_refc = 0;                                \
+                                                                       \
+  static int name##_enable(void *arg, dtrace_id_t id, void *parg)      \
+  {                                                                    \
+       int             rc = 0;                                         \
+                                                                       \
+       if (name##_refc++ == 0) {                                       \
+               if ((rc = try_module_get(THIS_MODULE)) == 0)            \
+                       return 0;                                       \
+       }                                                               \
+                                                                       \
+       if ((rc  = _##name##_enable(arg, id, parg)) != 0) {             \
+               if (--name##_refc == 0)                                 \
+                       module_put(THIS_MODULE);                        \
+       }                                                               \
+                                                                       \
+       return rc;                                                      \
+  }                                                                    \
+                                                                       \
+  static void name##_disable(void *arg, dtrace_id_t id, void *parg)    \
+  {                                                                    \
+       _##name##_disable(arg, id, parg);                               \
+                                                                       \
+       if (--name##_refc == 0)                                         \
+               module_put(THIS_MODULE);                                \
+  }
+
 #define DT_PROVIDER_MODULE(name, priv)                                 \
-  dtrace_provider_id_t name##_id;                                      \
+  dtrace_provider_id_t name##_id;                                      \
                                                                        \
   static int __init name##_init(void)                                  \
   {                                                                    \
index 8f96a8acb2dd3cc25ab0814a416cee5da9a5a40e..40949f8dce125bcd13bcd73e41b3644e3d7c7c77 100644 (file)
@@ -2,8 +2,8 @@
 #define _PROFILE_H_
 
 extern void profile_provide(void *, const dtrace_probedesc_t *);
-extern int profile_enable(void *, dtrace_id_t, void *);
-extern void profile_disable(void *, dtrace_id_t, void *);
+extern int _profile_enable(void *, dtrace_id_t, void *);
+extern void _profile_disable(void *, dtrace_id_t, void *);
 extern int profile_usermode(void *, dtrace_id_t, void *);
 extern void profile_destroy(void *, dtrace_id_t, void *);
 
index 38a65e4ac10c378f8ff1f43a5f2e553591a75e30..143a571bbc8c7659bd4850d819992828900f8314 100644 (file)
@@ -333,7 +333,7 @@ void profile_provide(void *arg, const dtrace_probedesc_t *desc)
        profile_create(interval, name, kind);
 }
 
-int profile_enable(void *arg, dtrace_id_t id, void *parg)
+int _profile_enable(void *arg, dtrace_id_t id, void *parg)
 {
        profile_probe_t         *prof = parg;
        cyc_omni_handler_t      omni;
@@ -367,7 +367,7 @@ int profile_enable(void *arg, dtrace_id_t id, void *parg)
        return 0;
 }
 
-void profile_disable(void *arg, dtrace_id_t id, void *parg)
+void _profile_disable(void *arg, dtrace_id_t id, void *parg)
 {
        profile_probe_t *prof = parg;
 
index 5ca3e4637b7ab5fa6c7455ea96e1a8158e692221..1a42a2e2f50e6f030f73bdfa2799d75f68cb63dc 100644 (file)
@@ -44,6 +44,8 @@ static const dtrace_pattr_t profile_attr = {
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
 };
 
+DT_PROVIDER_POPS(profile)
+
 static dtrace_pops_t profile_pops = {
        profile_provide,
        NULL,
index 504e380be1713da3d3d416318ad329e13406e04e..846afb9845639b0d2d1fec6144c902716bc3c20f 100644 (file)
@@ -142,7 +142,7 @@ void sdt_provide_module(void *arg, struct module *mp)
        }
 }
 
-int sdt_enable(void *arg, dtrace_id_t id, void *parg)
+int _sdt_enable(void *arg, dtrace_id_t id, void *parg)
 {
        sdt_probe_t     *sdp = parg;
 
@@ -150,7 +150,7 @@ int sdt_enable(void *arg, dtrace_id_t id, void *parg)
        return 0;
 }
 
-void sdt_disable(void *arg, dtrace_id_t id, void *parg)
+void _sdt_disable(void *arg, dtrace_id_t id, void *parg)
 {
        sdt_probe_t     *sdp = parg;
 
index 31a7788b13a9938a5a8670539691f9d6b90143e1..c6a066d56e1a1ec0c1c540531fc43d2aed45c90f 100644 (file)
@@ -23,8 +23,8 @@ typedef struct sdt_probe {
 extern dtrace_mprovider_t sdt_providers[];
 
 extern void sdt_provide_module(void *, struct module *);
-extern int sdt_enable(void *, dtrace_id_t, void *);
-extern void sdt_disable(void *, dtrace_id_t, void *);
+extern int _sdt_enable(void *, dtrace_id_t, void *);
+extern void _sdt_disable(void *, dtrace_id_t, void *);
 extern void sdt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
 extern uint64_t sdt_getarg(void *, dtrace_id_t, void *, int, int);
 extern void sdt_destroy(void *, dtrace_id_t, void *);
index cbb93d30691f9ab849ece8ad9b1ab85ae26fca98..55f7c862097e67cd970805a128588c2654f64ecf 100644 (file)
@@ -109,6 +109,8 @@ static dtrace_pattr_t iscsi_attr = {
 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_ISA },
 };
 
+DT_PROVIDER_POPS(sdt)
+
 static dtrace_pops_t sdt_pops = {
        NULL,
        sdt_provide_module,
index f53152bd59791204fb76bd481c6a7ebaaa2cc272..d726cb3a3282e61c9d8cc5320229a3a8af77f440 100644 (file)
@@ -27,8 +27,8 @@
 #include "dtrace.h"
 
 extern void systrace_provide(void *, const dtrace_probedesc_t *);
-extern int systrace_enable(void *arg, dtrace_id_t, void *);
-extern void systrace_disable(void *arg, dtrace_id_t, void *);
+extern int _systrace_enable(void *arg, dtrace_id_t, void *);
+extern void _systrace_disable(void *arg, dtrace_id_t, void *);
 extern void systrace_destroy(void *, dtrace_id_t, void *);
 
 extern dtrace_provider_id_t    syscall_id;
index 732db2653b6184dd5f84bc1709dc68e7fad429ab..50ea38862b766965f2aa3a24723b80f8de6f0b4b 100644 (file)
@@ -109,7 +109,7 @@ static dt_sys_call_t get_intercept(int sysnum)
        }
 }
 
-int systrace_enable(void *arg, dtrace_id_t id, void *parg)
+int _systrace_enable(void *arg, dtrace_id_t id, void *parg)
 {
        int             sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        int             enabled =
@@ -135,7 +135,7 @@ int systrace_enable(void *arg, dtrace_id_t id, void *parg)
        return 0;
 }
 
-void systrace_disable(void *arg, dtrace_id_t id, void *parg)
+void _systrace_disable(void *arg, dtrace_id_t id, void *parg)
 {
        int             sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        int             enabled =
index 4e87ec13350d2692681e40dd8ae7496f377b2ae9..3f89f8ea2f59b6bd26d1a41db3a0d96bda800982 100644 (file)
@@ -44,6 +44,8 @@ static const dtrace_pattr_t syscall_attr = {
 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
 };
 
+DT_PROVIDER_POPS(systrace)
+
 static dtrace_pops_t syscall_pops = {
        systrace_provide,
        NULL,
@@ -57,4 +59,4 @@ static dtrace_pops_t syscall_pops = {
        systrace_destroy
 };
 
-DT_PROVIDER_MODULE(syscall, DTRACE_PRIV_USER);
+DT_PROVIDER_MODULE(syscall, DTRACE_PRIV_USER)