From 474d745fffdcb195beae194471c63947aa03249a Mon Sep 17 00:00:00 2001 From: Pierre-Marc Fournier Date: Tue, 3 Mar 2009 15:08:04 -0500 Subject: [PATCH] ust: port tracepoints to userspace and add usage in hello.c --- hello/Makefile | 2 +- hello/hello.c | 4 +- libmarkers/Makefile | 2 +- libmarkers/marker.c | 2 +- libmarkers/marker.h | 4 +- libmarkers/tracepoint.c | 235 ++++++++++++++++++++++++++++------------ libmarkers/tracepoint.h | 74 ++++++++----- 7 files changed, 222 insertions(+), 101 deletions(-) diff --git a/hello/Makefile b/hello/Makefile index 1e65c5ef..8b7e4084 100644 --- a/hello/Makefile +++ b/hello/Makefile @@ -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: diff --git a/hello/hello.c b/hello/hello.c index 0533173d..5f05e225 100644 --- a/hello/hello.c +++ b/hello/hello.c @@ -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 diff --git a/libmarkers/Makefile b/libmarkers/Makefile index bf5539aa..746ea318 100644 --- a/libmarkers/Makefile +++ b/libmarkers/Makefile @@ -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 diff --git a/libmarkers/marker.c b/libmarkers/marker.c index 2fa723dc..ab0fc775 100644 --- a/libmarkers/marker.c +++ b/libmarkers/marker.c @@ -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(); } diff --git a/libmarkers/marker.h b/libmarkers/marker.h index 62954e1c..b7d5815c 100644 --- a/libmarkers/marker.h +++ b/libmarkers/marker.h @@ -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 diff --git a/libmarkers/tracepoint.c b/libmarkers/tracepoint.c index 2d67de0f..16292e43 100644 --- a/libmarkers/tracepoint.c +++ b/libmarkers/tracepoint.c @@ -15,23 +15,33 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct tracepoint __start___tracepoints[]; -extern struct tracepoint __stop___tracepoints[]; +//ust// #include +//ust// #include +//ust// #include +//ust// #include +//ust// #include +//ust// #include +//ust// #include +//ust// #include +//ust// #include +//ust// #include + +#include + +#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; +} diff --git a/libmarkers/tracepoint.h b/libmarkers/tracepoint.h index 860b6749..fda2aba9 100644 --- a/libmarkers/tracepoint.h +++ b/libmarkers/tracepoint.h @@ -14,9 +14,12 @@ * See the file COPYING for more details. */ -#include -#include -#include +//#include +//#include +//#include + +#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 -- 2.34.1