ust: port tracepoints to userspace and add usage in hello.c
authorPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Tue, 3 Mar 2009 20:08:04 +0000 (15:08 -0500)
committerPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Tue, 3 Mar 2009 20:08:04 +0000 (15:08 -0500)
hello/Makefile
hello/hello.c
libmarkers/Makefile
libmarkers/marker.c
libmarkers/marker.h
libmarkers/tracepoint.c
libmarkers/tracepoint.h

index 1e65c5ef6696f97c401806e85d151fc5486d87f1..8b7e40842298787987df6c410e3c976e39bb95bf 100644 (file)
@@ -2,7 +2,7 @@ all: hello
 
 hello: hello.c
 #dynamic version
-       gcc -g -I../libmarkers -I../share -I../libtracing -L../libmarkers -lmarkers -L../libtracectl -ltracectl -L../libtracing -ltracing $(CFLAGS) -Wl,-rpath ../../../../urcu -o hello hello.c
+       gcc -g -I../libmarkers -I../share -I../libtracing -L../libmarkers -lmarkers -L../libtracectl -ltracectl -L../libtracing -ltracing $(CFLAGS) -Wl,-rpath ../../../../urcu -o hello hello.c tp.c
        # -Wl,--print-map
 
 clean:
index 0533173dee211171e320d5868eeb325240121643..5f05e225641610960346a80773f57f55862d9bdc 100644 (file)
@@ -11,7 +11,7 @@
 #include "tracer.h"
 #include "marker-control.h"
 #include "relay.h"
-
+#include "tp.h"
 
 
 void probe(const struct marker *mdata,
@@ -66,6 +66,7 @@ int main()
        for(i=0; i<50; i++) {
                trace_mark(ust, bar, "str %s", "FOOBAZ");
                trace_mark(ust, bar2, "number1 %d number2 %d", 53, 9800);
+               trace_hello_tptest(i);
                usleep(100000);
        }
 
@@ -81,3 +82,4 @@ int main()
 }
 
 MARKER_LIB
+TRACEPOINT_LIB
index bf5539aa1ba91dab351428dc66e9c5cd9fa572b9..746ea3182024e82d175f46530f89edd8bbdb4836 100644 (file)
@@ -1,6 +1,6 @@
 all: libmarkers.so
 
 libmarkers.so: marker.c *.c *.h
-       gcc -g -fPIC -I../share -I../libtracing -I. -shared -o libmarkers.so -L../../../../urcu -I../../../../urcu $(CFLAGS) -lurcu marker.c ../share/kref.c ../libtracing/channels.c
+       gcc -g -fPIC -I../share -I../libtracing -I. -shared -o libmarkers.so -L../../../../urcu -I../../../../urcu $(CFLAGS) -lurcu marker.c tracepoint.c ../share/kref.c ../libtracing/channels.c
 
 .PHONY: libmarkers.so all
index 2fa723dc49e1cdfdc22b8a566f556881026bb566..ab0fc775adc422ba651a06e4430cfae1d589e19d 100644 (file)
@@ -726,7 +726,7 @@ static void marker_update_probes(void)
 //ust//        tracepoint_probe_update_all();
        /* Update immediate values */
        core_imv_update();
-//ust//        module_imv_update();
+//ust//        module_imv_update(); /* FIXME: need to port for libs? */
        marker_update_processes();
 }
 
index 62954e1c3f94a43c511164459ac76073c1fd73f4..b7d5815c65423038edc624fc3a9da7c4507a4a01 100644 (file)
@@ -293,6 +293,6 @@ static void __attribute__((constructor)) __markers__init(void)                              \
        marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker));\
 }
 
-#endif
-
 void marker_set_new_marker_cb(void (*cb)(struct marker *));
+
+#endif
index 2d67de0f8a6cab392daa6ec69368393393221a7a..16292e43202ccba14abc78fe42962dccdd610510 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/types.h>
-#include <linux/jhash.h>
-#include <linux/list.h>
-#include <linux/rcupdate.h>
-#include <linux/tracepoint.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/immediate.h>
-
-extern struct tracepoint __start___tracepoints[];
-extern struct tracepoint __stop___tracepoints[];
+//ust// #include <linux/module.h>
+//ust// #include <linux/mutex.h>
+//ust// #include <linux/types.h>
+//ust// #include <linux/jhash.h>
+//ust// #include <linux/list.h>
+//ust// #include <linux/rcupdate.h>
+//ust// #include <linux/tracepoint.h>
+//ust// #include <linux/err.h>
+//ust// #include <linux/slab.h>
+//ust// #include <linux/immediate.h>
+
+#include <errno.h>
+
+#include "kernelcompat.h"
+#include "tracepoint.h"
+#include "usterr.h"
+#include "list.h"
+
+//extern struct tracepoint __start___tracepoints[] __attribute__((visibility("hidden")));
+//extern struct tracepoint __stop___tracepoints[] __attribute__((visibility("hidden")));
 
 /* Set to 1 to enable tracepoint debug output */
 static const int tracepoint_debug;
 
+/* libraries that contain tracepoints (struct tracepoint_lib) */
+static LIST_HEAD(libs);
+
 /*
  * tracepoints_mutex nests inside module_mutex. Tracepoints mutex protects the
  * builtin and module tracepoints and the hash table.
@@ -61,7 +71,7 @@ struct tracepoint_entry {
 
 struct tp_probes {
        union {
-               struct rcu_head rcu;
+//ust//                struct rcu_head rcu;
                struct list_head list;
        } u;
        void *probes[0];
@@ -74,17 +84,19 @@ static inline void *allocate_probes(int count)
        return p == NULL ? NULL : p->probes;
 }
 
-static void rcu_free_old_probes(struct rcu_head *head)
-{
-       kfree(container_of(head, struct tp_probes, u.rcu));
-}
+//ust// static void rcu_free_old_probes(struct rcu_head *head)
+//ust// {
+//ust//        kfree(container_of(head, struct tp_probes, u.rcu));
+//ust// }
 
 static inline void release_probes(void *old)
 {
        if (old) {
                struct tp_probes *tp_probes = container_of(old,
                        struct tp_probes, probes[0]);
-               call_rcu_sched(&tp_probes->u.rcu, rcu_free_old_probes);
+//ust//                call_rcu_sched(&tp_probes->u.rcu, rcu_free_old_probes);
+               synchronize_rcu();
+               kfree(tp_probes);
        }
 }
 
@@ -298,13 +310,13 @@ void tracepoint_update_probe_range(struct tracepoint *begin,
 static void tracepoint_update_probes(void)
 {
        /* Core kernel tracepoints */
-       tracepoint_update_probe_range(__start___tracepoints,
-               __stop___tracepoints);
+//ust//        tracepoint_update_probe_range(__start___tracepoints,
+//ust//                __stop___tracepoints);
        /* tracepoints in modules. */
-       module_update_tracepoints();
+       lib_update_tracepoints();
        /* Update immediate values */
        core_imv_update();
-       module_imv_update();
+//ust//        module_imv_update();
 }
 
 static void *tracepoint_add_probe(const char *name, void *probe)
@@ -346,7 +358,7 @@ int tracepoint_probe_register(const char *name, void *probe)
        release_probes(old);
        return 0;
 }
-EXPORT_SYMBOL_GPL(tracepoint_probe_register);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register);
 
 static void *tracepoint_remove_probe(const char *name, void *probe)
 {
@@ -388,7 +400,7 @@ int tracepoint_probe_unregister(const char *name, void *probe)
        release_probes(old);
        return 0;
 }
-EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
 
 static LIST_HEAD(old_probes);
 static int need_update;
@@ -424,7 +436,7 @@ int tracepoint_probe_register_noupdate(const char *name, void *probe)
        mutex_unlock(&tracepoints_mutex);
        return 0;
 }
-EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
 
 /**
  * tracepoint_probe_unregister_noupdate -  remove a probe but not disconnect
@@ -447,7 +459,7 @@ int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
        mutex_unlock(&tracepoints_mutex);
        return 0;
 }
-EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
 
 /**
  * tracepoint_probe_update_all -  update tracepoints
@@ -470,10 +482,12 @@ void tracepoint_probe_update_all(void)
        tracepoint_update_probes();
        list_for_each_entry_safe(pos, next, &release_probes, u.list) {
                list_del(&pos->u.list);
-               call_rcu_sched(&pos->u.rcu, rcu_free_old_probes);
+//ust//                call_rcu_sched(&pos->u.rcu, rcu_free_old_probes);
+               synchronize_rcu();
+               kfree(pos);
        }
 }
-EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
 
 /**
  * tracepoint_get_iter_range - Get a next tracepoint iterator given a range.
@@ -496,21 +510,21 @@ int tracepoint_get_iter_range(struct tracepoint **tracepoint,
                return 1;
        return 0;
 }
-EXPORT_SYMBOL_GPL(tracepoint_get_iter_range);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_get_iter_range);
 
 static void tracepoint_get_iter(struct tracepoint_iter *iter)
 {
        int found = 0;
 
-       /* Core kernel tracepoints */
-       if (!iter->module) {
-               found = tracepoint_get_iter_range(&iter->tracepoint,
-                               __start___tracepoints, __stop___tracepoints);
-               if (found)
-                       goto end;
-       }
-       /* tracepoints in modules. */
-       found = module_get_iter_tracepoints(iter);
+//ust//        /* Core kernel tracepoints */
+//ust//        if (!iter->module) {
+//ust//                found = tracepoint_get_iter_range(&iter->tracepoint,
+//ust//                                __start___tracepoints, __stop___tracepoints);
+//ust//                if (found)
+//ust//                        goto end;
+//ust//        }
+       /* tracepoints in libs. */
+       found = lib_get_iter_tracepoints(iter);
 end:
        if (!found)
                tracepoint_iter_reset(iter);
@@ -520,7 +534,7 @@ void tracepoint_iter_start(struct tracepoint_iter *iter)
 {
        tracepoint_get_iter(iter);
 }
-EXPORT_SYMBOL_GPL(tracepoint_iter_start);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_start);
 
 void tracepoint_iter_next(struct tracepoint_iter *iter)
 {
@@ -532,49 +546,136 @@ void tracepoint_iter_next(struct tracepoint_iter *iter)
         */
        tracepoint_get_iter(iter);
 }
-EXPORT_SYMBOL_GPL(tracepoint_iter_next);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_next);
 
 void tracepoint_iter_stop(struct tracepoint_iter *iter)
 {
 }
-EXPORT_SYMBOL_GPL(tracepoint_iter_stop);
+//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_stop);
 
 void tracepoint_iter_reset(struct tracepoint_iter *iter)
 {
-       iter->module = NULL;
+//ust//        iter->module = NULL;
        iter->tracepoint = NULL;
 }
-EXPORT_SYMBOL_GPL(tracepoint_iter_reset);
-
-#ifdef CONFIG_MODULES
+//ust// EXPORT_SYMBOL_GPL(tracepoint_iter_reset);
+
+//ust// #ifdef CONFIG_MODULES
+
+//ust// int tracepoint_module_notify(struct notifier_block *self,
+//ust//                             unsigned long val, void *data)
+//ust// {
+//ust//        struct module *mod = data;
+//ust// 
+//ust//        switch (val) {
+//ust//        case MODULE_STATE_COMING:
+//ust//                tracepoint_update_probe_range(mod->tracepoints,
+//ust//                        mod->tracepoints + mod->num_tracepoints);
+//ust//                break;
+//ust//        case MODULE_STATE_GOING:
+//ust//                tracepoint_update_probe_range(mod->tracepoints,
+//ust//                        mod->tracepoints + mod->num_tracepoints);
+//ust//                break;
+//ust//        }
+//ust//        return 0;
+//ust// }
+
+//ust// struct notifier_block tracepoint_module_nb = {
+//ust//        .notifier_call = tracepoint_module_notify,
+//ust//        .priority = 0,
+//ust// };
+
+//ust// static int init_tracepoints(void)
+//ust// {
+//ust//        return register_module_notifier(&tracepoint_module_nb);
+//ust// }
+//ust// __initcall(init_tracepoints);
+
+//ust// #endif /* CONFIG_MODULES */
 
-int tracepoint_module_notify(struct notifier_block *self,
-                            unsigned long val, void *data)
+/*
+ * Returns 0 if current not found.
+ * Returns 1 if current found.
+ */
+int lib_get_iter_tracepoints(struct tracepoint_iter *iter)
 {
-       struct module *mod = data;
+       struct tracepoint_lib *iter_lib;
+       int found = 0;
 
-       switch (val) {
-       case MODULE_STATE_COMING:
-               tracepoint_update_probe_range(mod->tracepoints,
-                       mod->tracepoints + mod->num_tracepoints);
-               break;
-       case MODULE_STATE_GOING:
-               tracepoint_update_probe_range(mod->tracepoints,
-                       mod->tracepoints + mod->num_tracepoints);
-               break;
+//ust//        mutex_lock(&module_mutex);
+       list_for_each_entry(iter_lib, &libs, list) {
+               if (iter_lib < iter->lib)
+                       continue;
+               else if (iter_lib > iter->lib)
+                       iter->tracepoint = NULL;
+               found = marker_get_iter_range(&iter->tracepoint,
+                       iter_lib->tracepoints_start,
+                       iter_lib->tracepoints_start + iter_lib->tracepoints_count);
+               if (found) {
+                       iter->lib = iter_lib;
+                       break;
+               }
        }
-       return 0;
+//ust//        mutex_unlock(&module_mutex);
+       return found;
 }
 
-struct notifier_block tracepoint_module_nb = {
-       .notifier_call = tracepoint_module_notify,
-       .priority = 0,
-};
+void lib_update_tracepoints(void)
+{
+       struct tracepoint_lib *lib;
+
+//ust//        mutex_lock(&module_mutex);
+       list_for_each_entry(lib, &libs, list)
+               tracepoint_update_probe_range(lib->tracepoints_start,
+                               lib->tracepoints_start + lib->tracepoints_count);
+//ust//        mutex_unlock(&module_mutex);
+}
+
+static void (*new_tracepoint_cb)(struct tracepoint *) = NULL;
+
+void tracepoint_set_new_tracepoint_cb(void (*cb)(struct tracepoint *))
+{
+       new_tracepoint_cb = cb;
+}
 
-static int init_tracepoints(void)
+static void new_tracepoints(struct tracepoint *start, struct tracepoint *end)
 {
-       return register_module_notifier(&tracepoint_module_nb);
+       if(new_tracepoint_cb) {
+               struct tracepoint *t;
+               for(t=start; t < end; t++) {
+                       new_tracepoint_cb(t);
+               }
+       }
 }
-__initcall(init_tracepoints);
 
-#endif /* CONFIG_MODULES */
+int tracepoint_register_lib(struct tracepoint *tracepoints_start, int tracepoints_count)
+{
+       struct tracepoint_lib *pl;
+
+       pl = (struct tracepoint_lib *) malloc(sizeof(struct tracepoint_lib));
+
+       pl->tracepoints_start = tracepoints_start;
+       pl->tracepoints_count = tracepoints_count;
+
+       /* FIXME: maybe protect this with its own mutex? */
+       mutex_lock(&tracepoints_mutex);
+       list_add(&pl->list, &libs);
+       mutex_unlock(&tracepoints_mutex);
+
+       new_tracepoints(tracepoints_start, tracepoints_start + tracepoints_count);
+
+       /* FIXME: update just the loaded lib */
+       lib_update_tracepoints();
+
+       DBG("just registered a tracepoints section from %p and having %d tracepoints", tracepoints_start, tracepoints_count);
+       
+       return 0;
+}
+
+int tracepoint_unregister_lib(struct tracepoint *tracepoints_start, int tracepoints_count)
+{
+       /*FIXME: implement; but before implementing, tracepoint_register_lib must
+          have appropriate locking. */
+
+       return 0;
+}
index 860b674978ba47a85df3a820de5478de0d378093..fda2aba900906bab5a440ad662e2375d6305336c 100644 (file)
  * See the file COPYING for more details.
  */
 
-#include <linux/immediate.h>
-#include <linux/types.h>
-#include <linux/rcupdate.h>
+//#include <linux/immediate.h>
+//#include <linux/types.h>
+//#include <linux/rcupdate.h>
+
+#include "immediate.h"
+#include "kernelcompat.h"
 
 struct module;
 struct tracepoint;
@@ -35,7 +38,7 @@ struct tracepoint {
 #define TPPROTO(args...)       args
 #define TPARGS(args...)                args
 
-#ifdef CONFIG_TRACEPOINTS
+//ust// #ifdef CONFIG_TRACEPOINTS
 
 /*
  * it_func[0] is never NULL because there is at least one element in the array
@@ -112,29 +115,29 @@ struct tracepoint {
 extern void tracepoint_update_probe_range(struct tracepoint *begin,
        struct tracepoint *end);
 
-#else /* !CONFIG_TRACEPOINTS */
-#define DECLARE_TRACE(name, proto, args)                               \
-       static inline void trace_##name(proto)                          \
-       { }                                                             \
-       static inline void _trace_##name(proto)                         \
-       { }                                                             \
-       static inline int register_trace_##name(void (*probe)(proto))   \
-       {                                                               \
-               return -ENOSYS;                                         \
-       }                                                               \
-       static inline int unregister_trace_##name(void (*probe)(proto)) \
-       {                                                               \
-               return -ENOSYS;                                         \
-       }
-
-#define DEFINE_TRACE(name)
-#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
-#define EXPORT_TRACEPOINT_SYMBOL(name)
-
-static inline void tracepoint_update_probe_range(struct tracepoint *begin,
-       struct tracepoint *end)
-{ }
-#endif /* CONFIG_TRACEPOINTS */
+//ust// #else /* !CONFIG_TRACEPOINTS */
+//ust// #define DECLARE_TRACE(name, proto, args)                               \
+//ust//        static inline void trace_##name(proto)                          \
+//ust//        { }                                                             \
+//ust//        static inline void _trace_##name(proto)                         \
+//ust//        { }                                                             \
+//ust//        static inline int register_trace_##name(void (*probe)(proto))   \
+//ust//        {                                                               \
+//ust//                return -ENOSYS;                                         \
+//ust//        }                                                               \
+//ust//        static inline int unregister_trace_##name(void (*probe)(proto)) \
+//ust//        {                                                               \
+//ust//                return -ENOSYS;                                         \
+//ust//        }
+//ust// 
+//ust// #define DEFINE_TRACE(name)
+//ust// #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
+//ust// #define EXPORT_TRACEPOINT_SYMBOL(name)
+//ust// 
+//ust// static inline void tracepoint_update_probe_range(struct tracepoint *begin,
+//ust//        struct tracepoint *end)
+//ust// { }
+//ust// #endif /* CONFIG_TRACEPOINTS */
 
 /*
  * Connect a probe to a tracepoint.
@@ -153,7 +156,8 @@ extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
 extern void tracepoint_probe_update_all(void);
 
 struct tracepoint_iter {
-       struct module *module;
+//ust//        struct module *module;
+       struct tracepoint_lib *lib;
        struct tracepoint *tracepoint;
 };
 
@@ -174,4 +178,18 @@ static inline void tracepoint_synchronize_unregister(void)
        synchronize_sched();
 }
 
+struct tracepoint_lib {
+       struct tracepoint *tracepoints_start;
+       int tracepoints_count;
+       struct list_head list;
+};
+
+#define TRACEPOINT_LIB                                                                 \
+extern struct tracepoint __start___tracepoints[] __attribute__((visibility("hidden")));                \
+extern struct tracepoint __stop___tracepoints[] __attribute__((visibility("hidden")));         \
+                                                                                       \
+static void __attribute__((constructor)) __tracepoints__init(void)                             \
+{                                                                                      \
+       tracepoint_register_lib(__start___tracepoints, (((long)__stop___tracepoints)-((long)__start___tracepoints))/sizeof(struct tracepoint));\
+}
 #endif
This page took 0.037296 seconds and 4 git commands to generate.