[ltt-dev] [UST commit] Markers: sync from LTTng 0.249 marker code
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Thu May 19 18:30:15 EDT 2011
commit fd0a1aea7b67696a87ffe70b8d3d8c15424f0bca
Author: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
Date: Thu May 19 18:29:38 2011 -0400
Markers: sync from LTTng 0.249 marker code
- Add missing mutexes.
- Cleanup RCU usage.
- Remove unused code.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
diff --git a/include/ust/marker-internal.h b/include/ust/marker-internal.h
index 0422908..6a71ebe 100644
--- a/include/ust/marker-internal.h
+++ b/include/ust/marker-internal.h
@@ -68,9 +68,6 @@
#define ust_marker_tp(name, tp_name, tp_cb, format, args...) \
__ust_marker_tp(ust, name, NULL, tp_name, tp_cb, format, ## args)
-extern void ust_marker_update_probe_range(struct ust_marker * const *begin,
- struct ust_marker * const *end);
-
extern void lock_ust_marker(void);
extern void unlock_ust_marker(void);
@@ -115,10 +112,7 @@ extern void ust_marker_iter_start(struct ust_marker_iter *iter);
extern void ust_marker_iter_next(struct ust_marker_iter *iter);
extern void ust_marker_iter_stop(struct ust_marker_iter *iter);
extern void ust_marker_iter_reset(struct ust_marker_iter *iter);
-extern int ust_marker_get_iter_range(struct ust_marker * const **marker, struct ust_marker * const *begin,
- struct ust_marker * const *end);
-extern void ust_marker_update_process(void);
extern int is_ust_marker_enabled(const char *channel, const char *name);
extern void ust_marker_set_new_ust_marker_cb(void (*cb)(struct ust_marker *));
diff --git a/include/ust/marker.h b/include/ust/marker.h
index af15ad4..e8608a9 100644
--- a/include/ust/marker.h
+++ b/include/ust/marker.h
@@ -32,6 +32,7 @@
#include <urcu/list.h>
struct ust_marker;
+struct ust_marker_probe_array;
/**
* ust_marker_probe_func - Type of a marker probe function
@@ -68,7 +69,7 @@ struct ust_marker {
uint16_t event_id; /* Numeric event identifier, dynamic */
void (*call)(const struct ust_marker *mdata, void *call_private, ...);
struct ust_marker_probe_closure single;
- struct ust_marker_probe_closure *multi;
+ struct ust_marker_probe_array *multi;
const char *tp_name; /* Optional tracepoint name */
void *tp_cb; /* Optional tracepoint callback */
};
diff --git a/libust/marker.c b/libust/marker.c
index 33827fd..3c3a5b7 100644
--- a/libust/marker.c
+++ b/libust/marker.c
@@ -34,9 +34,6 @@
#include "tracercore.h"
#include "tracer.h"
-__thread long ust_reg_stack[500];
-volatile __thread long *ust_reg_stack_ptr = (long *) 0;
-
extern struct ust_marker * const __start___ust_marker_ptrs[] __attribute__((visibility("hidden")));
extern struct ust_marker * const __stop___ust_marker_ptrs[] __attribute__((visibility("hidden")));
@@ -44,14 +41,12 @@ extern struct ust_marker * const __stop___ust_marker_ptrs[] __attribute__((visib
static const int ust_marker_debug;
/*
- * ust_marker_mutex nests inside module_mutex. ust_marker mutex protects
- * the builtin and module ust_marker and the hash table.
+ * ust_marker mutex protects the builtin and module ust_marker and the
+ * hash table, as well as the ust_marker_libs list.
*/
static DEFINE_MUTEX(ust_marker_mutex);
-
static CDS_LIST_HEAD(ust_marker_libs);
-
void lock_ust_marker(void)
{
pthread_mutex_lock(&ust_marker_mutex);
@@ -64,12 +59,17 @@ void unlock_ust_marker(void)
/*
* ust_marker hash table, containing the active ust_marker.
- * Protected by module_mutex.
+ * Protected by ust_marker mutex.
*/
#define UST_MARKER_HASH_BITS 6
#define UST_MARKER_TABLE_SIZE (1 << UST_MARKER_HASH_BITS)
static struct cds_hlist_head ust_marker_table[UST_MARKER_TABLE_SIZE];
+struct ust_marker_probe_array {
+ struct rcu_head rcu;
+ struct ust_marker_probe_closure c[0];
+};
+
/*
* Note about RCU :
* It is used to make sure every handler has finished using its private
@@ -85,11 +85,8 @@ struct ust_marker_entry {
/* Probe wrapper */
void (*call)(const struct ust_marker *mdata, void *call_private, ...);
struct ust_marker_probe_closure single;
- struct ust_marker_probe_closure *multi;
+ struct ust_marker_probe_array *multi;
int refcount; /* Number of times armed. 0 if disarmed. */
- struct rcu_head rcu;
- void *oldptr;
- int rcu_pending;
u16 channel_id;
u16 event_id;
unsigned char ptype:1;
@@ -97,14 +94,6 @@ struct ust_marker_entry {
char channel[0]; /* Contains channel'\0'name'\0'format'\0' */
};
-#ifdef CONFIG_UST_MARKER_USERSPACE
-static void ust_marker_update_processes(void);
-#else
-static void ust_marker_update_processes(void)
-{
-}
-#endif
-
/**
* __ust_marker_empty_function - Empty probe callback
* @mdata: ust_marker data
@@ -123,7 +112,6 @@ notrace void __ust_marker_empty_function(const struct ust_marker *mdata,
void *probe_private, void *call_private, const char *fmt, va_list *args)
{
}
-//ust// EXPORT_SYMBOL_GPL(__ust_marker_empty_function);
/*
* ust_marker_probe_cb Callback that prepares the variable argument list for probes.
@@ -146,7 +134,7 @@ notrace void ust_marker_probe_cb(const struct ust_marker *mdata,
* sure the teardown of the callbacks can be done correctly when they
* are in modules and they insure RCU read coherency.
*/
-//ust// rcu_read_lock_sched_notrace();
+ rcu_read_lock();
ptype = mdata->ptype;
if (likely(!ptype)) {
ust_marker_probe_func *func;
@@ -162,7 +150,7 @@ notrace void ust_marker_probe_cb(const struct ust_marker *mdata,
mdata->format, &args);
va_end(args);
} else {
- struct ust_marker_probe_closure *multi;
+ struct ust_marker_probe_array *multi;
int i;
/*
* Read mdata->ptype before mdata->multi.
@@ -177,16 +165,15 @@ notrace void ust_marker_probe_cb(const struct ust_marker *mdata,
* in the fast path, so put the explicit cmm_barrier here.
*/
cmm_smp_read_barrier_depends();
- for (i = 0; multi[i].func; i++) {
+ for (i = 0; multi->c[i].func; i++) {
va_start(args, call_private);
- multi[i].func(mdata, multi[i].probe_private,
+ multi->c[i].func(mdata, multi->c[i].probe_private,
call_private, mdata->format, &args);
va_end(args);
}
}
-//ust// rcu_read_unlock_sched_notrace();
+ rcu_read_unlock();
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_probe_cb);
/*
* ust_marker_probe_cb Callback that does not prepare the variable argument list.
@@ -202,7 +189,7 @@ static notrace void ust_marker_probe_cb_noarg(const struct ust_marker *mdata,
va_list args; /* not initialized */
char ptype;
-//ust// rcu_read_lock_sched_notrace();
+ rcu_read_lock();
ptype = mdata->ptype;
if (likely(!ptype)) {
ust_marker_probe_func *func;
@@ -216,7 +203,7 @@ static notrace void ust_marker_probe_cb_noarg(const struct ust_marker *mdata,
func(mdata, mdata->single.probe_private, call_private,
mdata->format, &args);
} else {
- struct ust_marker_probe_closure *multi;
+ struct ust_marker_probe_array *multi;
int i;
/*
* Read mdata->ptype before mdata->multi.
@@ -231,21 +218,18 @@ static notrace void ust_marker_probe_cb_noarg(const struct ust_marker *mdata,
* in the fast path, so put the explicit cmm_barrier here.
*/
cmm_smp_read_barrier_depends();
- for (i = 0; multi[i].func; i++)
- multi[i].func(mdata, multi[i].probe_private,
+ for (i = 0; multi->c[i].func; i++)
+ multi->c[i].func(mdata, multi->c[i].probe_private,
call_private, mdata->format, &args);
}
-//ust// rcu_read_unlock_sched_notrace();
+ rcu_read_unlock();
}
static void free_old_closure(struct rcu_head *head)
{
- struct ust_marker_entry *entry = _ust_container_of(head,
- struct ust_marker_entry, rcu);
- free(entry->oldptr);
- /* Make sure we free the data before setting the pending flag to 0 */
- cmm_smp_wmb();
- entry->rcu_pending = 0;
+ struct ust_marker_probe_array *multi =
+ _ust_container_of(head, struct ust_marker_probe_array, rcu);
+ free(multi);
}
static void debug_print_probes(struct ust_marker_entry *entry)
@@ -260,19 +244,19 @@ static void debug_print_probes(struct ust_marker_entry *entry)
entry->single.func,
entry->single.probe_private);
} else {
- for (i = 0; entry->multi[i].func; i++)
+ for (i = 0; entry->multi->c[i].func; i++)
DBG("Multi probe %d : %p %p", i,
- entry->multi[i].func,
- entry->multi[i].probe_private);
+ entry->multi->c[i].func,
+ entry->multi->c[i].probe_private);
}
}
-static struct ust_marker_probe_closure *
+static struct ust_marker_probe_array *
ust_marker_entry_add_probe(struct ust_marker_entry *entry,
ust_marker_probe_func *probe, void *probe_private)
{
int nr_probes = 0;
- struct ust_marker_probe_closure *old, *new;
+ struct ust_marker_probe_array *old, *new;
WARN_ON(!probe);
@@ -297,23 +281,24 @@ ust_marker_entry_add_probe(struct ust_marker_entry *entry,
}
} else {
/* (N -> N+1), (N != 0, 1) probes */
- for (nr_probes = 0; old[nr_probes].func; nr_probes++)
- if (old[nr_probes].func == probe
- && old[nr_probes].probe_private
+ for (nr_probes = 0; old->c[nr_probes].func; nr_probes++)
+ if (old->c[nr_probes].func == probe
+ && old->c[nr_probes].probe_private
== probe_private)
return ERR_PTR(-EBUSY);
}
/* + 2 : one for new probe, one for NULL func */
- new = zmalloc((nr_probes + 2) * sizeof(struct ust_marker_probe_closure));
+ new = zmalloc(sizeof(struct ust_marker_probe_array)
+ + ((nr_probes + 2) * sizeof(struct ust_marker_probe_closure)));
if (new == NULL)
return ERR_PTR(-ENOMEM);
if (!old)
- new[0] = entry->single;
+ new->c[0] = entry->single;
else
- memcpy(new, old,
+ memcpy(&new->c[0], &old->c[0],
nr_probes * sizeof(struct ust_marker_probe_closure));
- new[nr_probes].func = probe;
- new[nr_probes].probe_private = probe_private;
+ new->c[nr_probes].func = probe;
+ new->c[nr_probes].probe_private = probe_private;
entry->refcount = nr_probes + 1;
entry->multi = new;
entry->ptype = 1;
@@ -321,12 +306,12 @@ ust_marker_entry_add_probe(struct ust_marker_entry *entry,
return old;
}
-static struct ust_marker_probe_closure *
+static struct ust_marker_probe_array *
ust_marker_entry_remove_probe(struct ust_marker_entry *entry,
ust_marker_probe_func *probe, void *probe_private)
{
int nr_probes = 0, nr_del = 0, i;
- struct ust_marker_probe_closure *old, *new;
+ struct ust_marker_probe_array *old, *new;
old = entry->multi;
@@ -344,9 +329,9 @@ ust_marker_entry_remove_probe(struct ust_marker_entry *entry,
return NULL;
} else {
/* (N -> M), (N > 1, M >= 0) probes */
- for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
- if ((!probe || old[nr_probes].func == probe)
- && old[nr_probes].probe_private
+ for (nr_probes = 0; old->c[nr_probes].func; nr_probes++) {
+ if ((!probe || old->c[nr_probes].func == probe)
+ && old->c[nr_probes].probe_private
== probe_private)
nr_del++;
}
@@ -359,23 +344,24 @@ ust_marker_entry_remove_probe(struct ust_marker_entry *entry,
entry->ptype = 0;
} else if (nr_probes - nr_del == 1) {
/* N -> 1, (N > 1) */
- for (i = 0; old[i].func; i++)
- if ((probe && old[i].func != probe) ||
- old[i].probe_private != probe_private)
- entry->single = old[i];
+ for (i = 0; old->c[i].func; i++)
+ if ((probe && old->c[i].func != probe) ||
+ old->c[i].probe_private != probe_private)
+ entry->single = old->c[i];
entry->refcount = 1;
entry->ptype = 0;
} else {
int j = 0;
/* N -> M, (N > 1, M > 1) */
/* + 1 for NULL */
- new = zmalloc((nr_probes - nr_del + 1) * sizeof(struct ust_marker_probe_closure));
+ new = zmalloc(sizeof(struct ust_marker_probe_array)
+ + ((nr_probes - nr_del + 1) * sizeof(struct ust_marker_probe_closure)));
if (new == NULL)
return ERR_PTR(-ENOMEM);
- for (i = 0; old[i].func; i++)
- if ((probe && old[i].func != probe) ||
- old[i].probe_private != probe_private)
- new[j++] = old[i];
+ for (i = 0; old->c[i].func; i++)
+ if ((probe && old->c[i].func != probe) ||
+ old->c[i].probe_private != probe_private)
+ new->c[j++] = old->c[i];
entry->refcount = nr_probes - nr_del;
entry->ptype = 1;
entry->multi = new;
@@ -463,7 +449,6 @@ static struct ust_marker_entry *add_ust_marker(const char *channel, const char *
e->ptype = 0;
e->format_allocated = 0;
e->refcount = 0;
- e->rcu_pending = 0;
cds_hlist_add_head(&e->hlist, head);
return e;
}
@@ -500,9 +485,6 @@ static int remove_ust_marker(const char *channel, const char *name)
free(e->format);
ret = ltt_channels_unregister(e->channel);
WARN_ON(ret);
- /* Make sure the call_rcu has been executed */
-//ust// if (e->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
free(e);
return 0;
}
@@ -590,26 +572,17 @@ static int set_ust_marker(struct ust_marker_entry *entry, struct ust_marker *ele
*/
if (active) {
- /*
- * try_module_get should always succeed because we hold
- * ust_marker_mutex to get the tp_cb address.
- */
-//ust// ret = try_module_get(__module_text_address(
-//ust// (unsigned long)elem->tp_cb));
-//ust// BUG_ON(!ret);
ret = tracepoint_probe_register_noupdate(
elem->tp_name,
elem->tp_cb, NULL);
} else {
- ret = tracepoint_probe_unregister_noupdate(
- elem->tp_name,
- elem->tp_cb, NULL);
/*
* tracepoint_probe_update_all() must be called
- * before the module containing tp_cb is unloaded.
+ * before the library containing tp_cb is unloaded.
*/
-//ust// module_put(__module_text_address(
-//ust// (unsigned long)elem->tp_cb));
+ ret = tracepoint_probe_unregister_noupdate(
+ elem->tp_name,
+ elem->tp_cb, NULL);
}
}
elem->state = active;
@@ -621,7 +594,7 @@ static int set_ust_marker(struct ust_marker_entry *entry, struct ust_marker *ele
* Disable a ust_marker and its probe callback.
* Note: only waiting an RCU period after setting elem->call to the empty
* function insures that the original callback is not used anymore. This insured
- * by rcu_read_lock_sched around the call site.
+ * by rcu_read_lock around the call site.
*/
static void disable_ust_marker(struct ust_marker *elem)
{
@@ -634,14 +607,13 @@ static void disable_ust_marker(struct ust_marker *elem)
* It is ok to directly call the probe registration because type
* checking has been done in the __ust_marker_tp() macro.
*/
- ret = tracepoint_probe_unregister_noupdate(elem->tp_name,
- elem->tp_cb, NULL);
- WARN_ON(ret);
/*
* tracepoint_probe_update_all() must be called
* before the module containing tp_cb is unloaded.
*/
-//ust// module_put(__module_text_address((unsigned long)elem->tp_cb));
+ ret = tracepoint_probe_unregister_noupdate(elem->tp_name,
+ elem->tp_cb, NULL);
+ WARN_ON(ret);
}
elem->state = 0;
elem->single.func = __ust_marker_empty_function;
@@ -680,13 +652,13 @@ int is_ust_marker_enabled(const char *channel, const char *name)
*
* Updates the probe callback corresponding to a range of ust_marker.
*/
+static
void ust_marker_update_probe_range(struct ust_marker * const *begin,
struct ust_marker * const *end)
{
struct ust_marker * const *iter;
struct ust_marker_entry *mark_entry;
- pthread_mutex_lock(&ust_marker_mutex);
for (iter = begin; iter < end; iter++) {
if (!*iter)
continue; /* skip dummy */
@@ -700,19 +672,17 @@ void ust_marker_update_probe_range(struct ust_marker * const *begin,
disable_ust_marker(*iter);
}
}
- pthread_mutex_unlock(&ust_marker_mutex);
}
static void lib_update_ust_marker(void)
{
struct ust_marker_lib *lib;
- /* FIXME: we should probably take a mutex here on libs */
-//ust// pthread_mutex_lock(&module_mutex);
+ pthread_mutex_lock(&ust_marker_mutex);
cds_list_for_each_entry(lib, &ust_marker_libs, list)
ust_marker_update_probe_range(lib->ust_marker_start,
lib->ust_marker_start + lib->ust_marker_count);
-//ust// pthread_mutex_unlock(&module_mutex);
+ pthread_mutex_unlock(&ust_marker_mutex);
}
/*
@@ -736,7 +706,6 @@ static void ust_marker_update_probes(void)
{
lib_update_ust_marker();
tracepoint_probe_update_all();
- ust_marker_update_processes();
}
/**
@@ -757,7 +726,7 @@ int ust_marker_probe_register(const char *channel, const char *name,
{
struct ust_marker_entry *entry;
int ret = 0, ret_err;
- struct ust_marker_probe_closure *old;
+ struct ust_marker_probe_array *old;
int first_probe = 0;
pthread_mutex_lock(&ust_marker_mutex);
@@ -797,12 +766,6 @@ int ust_marker_probe_register(const char *channel, const char *name,
goto end;
}
- /*
- * If we detect that a call_rcu is pending for this ust_marker,
- * make sure it's executed now.
- */
-//ust// if (entry->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
old = ust_marker_entry_add_probe(entry, probe, probe_private);
if (IS_ERR(old)) {
ret = PTR_ERR(old);
@@ -816,19 +779,11 @@ int ust_marker_probe_register(const char *channel, const char *name,
/* Activate ust_marker if necessary */
ust_marker_update_probes();
- pthread_mutex_lock(&ust_marker_mutex);
- entry = get_ust_marker(channel, name);
- if (!entry)
- goto end;
-//ust// if (entry->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
- entry->oldptr = old;
- entry->rcu_pending = 1;
- /* write rcu_pending before calling the RCU callback */
- cmm_smp_wmb();
-//ust// call_rcu_sched(&entry->rcu, free_old_closure);
- synchronize_rcu(); free_old_closure(&entry->rcu);
- goto end;
+ if (old) {
+ synchronize_rcu();
+ free_old_closure(&old->rcu);
+ }
+ return ret;
error_unregister_channel:
ret_err = ltt_channels_unregister(channel);
@@ -840,7 +795,6 @@ end:
pthread_mutex_unlock(&ust_marker_mutex);
return ret;
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_probe_register);
/**
* ust_marker_probe_unregister - Disconnect a probe from a ust_marker
@@ -859,42 +813,34 @@ int ust_marker_probe_unregister(const char *channel, const char *name,
ust_marker_probe_func *probe, void *probe_private)
{
struct ust_marker_entry *entry;
- struct ust_marker_probe_closure *old;
- int ret = -ENOENT;
+ struct ust_marker_probe_array *old;
+ int ret = 0;
pthread_mutex_lock(&ust_marker_mutex);
entry = get_ust_marker(channel, name);
- if (!entry)
+ if (!entry) {
+ ret = -ENOENT;
goto end;
-//ust// if (entry->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
+ }
old = ust_marker_entry_remove_probe(entry, probe, probe_private);
pthread_mutex_unlock(&ust_marker_mutex);
ust_marker_update_probes();
- pthread_mutex_lock(&ust_marker_mutex);
- entry = get_ust_marker(channel, name);
- if (!entry)
- goto end;
-//ust// if (entry->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
- entry->oldptr = old;
- entry->rcu_pending = 1;
- /* write rcu_pending before calling the RCU callback */
- cmm_smp_wmb();
-//ust// call_rcu_sched(&entry->rcu, free_old_closure);
- synchronize_rcu(); free_old_closure(&entry->rcu);
- remove_ust_marker(channel, name); /* Ignore busy error message */
- ret = 0;
+ if (old) {
+ synchronize_rcu();
+ free_old_closure(&old->rcu);
+ }
+ return ret;
+
end:
pthread_mutex_unlock(&ust_marker_mutex);
return ret;
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_probe_unregister);
static struct ust_marker_entry *
-get_ust_marker_from_private_data(ust_marker_probe_func *probe, void *probe_private)
+get_ust_marker_from_private_data(ust_marker_probe_func *probe,
+ void *probe_private)
{
struct ust_marker_entry *entry;
unsigned int i;
@@ -910,11 +856,11 @@ get_ust_marker_from_private_data(ust_marker_probe_func *probe, void *probe_priva
== probe_private)
return entry;
} else {
- struct ust_marker_probe_closure *closure;
+ struct ust_marker_probe_array *closure;
closure = entry->multi;
- for (i = 0; closure[i].func; i++) {
- if (closure[i].func == probe &&
- closure[i].probe_private
+ for (i = 0; closure->c[i].func; i++) {
+ if (closure->c[i].func == probe &&
+ closure->c[i].probe_private
== probe_private)
return entry;
}
@@ -942,45 +888,37 @@ int ust_marker_probe_unregister_private_data(ust_marker_probe_func *probe,
{
struct ust_marker_entry *entry;
int ret = 0;
- struct ust_marker_probe_closure *old;
+ struct ust_marker_probe_array *old;
char *channel = NULL, *name = NULL;
pthread_mutex_lock(&ust_marker_mutex);
entry = get_ust_marker_from_private_data(probe, probe_private);
if (!entry) {
ret = -ENOENT;
- goto end;
+ goto unlock;
}
-//ust// if (entry->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
old = ust_marker_entry_remove_probe(entry, NULL, probe_private);
channel = strdup(entry->channel);
name = strdup(entry->name);
+ /* Ignore busy error message */
+ remove_ust_marker(channel, name);
pthread_mutex_unlock(&ust_marker_mutex);
ust_marker_update_probes();
- pthread_mutex_lock(&ust_marker_mutex);
- entry = get_ust_marker(channel, name);
- if (!entry)
- goto end;
-//ust// if (entry->rcu_pending)
-//ust// rcu_cmm_barrier_sched();
- entry->oldptr = old;
- entry->rcu_pending = 1;
- /* write rcu_pending before calling the RCU callback */
- cmm_smp_wmb();
-//ust// call_rcu_sched(&entry->rcu, free_old_closure);
- synchronize_rcu(); free_old_closure(&entry->rcu);
- /* Ignore busy error message */
- remove_ust_marker(channel, name);
-end:
+ if (old) {
+ synchronize_rcu();
+ free_old_closure(&old->rcu);
+ }
+ goto end;
+
+unlock:
pthread_mutex_unlock(&ust_marker_mutex);
+end:
free(channel);
free(name);
return ret;
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_probe_unregister_private_data);
/**
* ust_marker_get_private_data - Get a ust_marker's probe private data
@@ -1015,14 +953,14 @@ void *ust_marker_get_private_data(const char *channel, const char *name,
if (num == 0 && e->single.func == probe)
return e->single.probe_private;
} else {
- struct ust_marker_probe_closure *closure;
+ struct ust_marker_probe_array *closure;
int match = 0;
closure = e->multi;
- for (i = 0; closure[i].func; i++) {
- if (closure[i].func != probe)
+ for (i = 0; closure->c[i].func; i++) {
+ if (closure->c[i].func != probe)
continue;
if (match++ == num)
- return closure[i].probe_private;
+ return closure->c[i].probe_private;
}
}
break;
@@ -1030,48 +968,44 @@ void *ust_marker_get_private_data(const char *channel, const char *name,
}
return ERR_PTR(-ENOENT);
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_get_private_data);
/**
- * ust_marker_compact_event_ids - Compact ust_marker event IDs and reassign channels
+ * ust_marker_get_iter_range - Get a next ust_marker iterator given a range.
+ * @ust_marker: current ust_marker (in), next ust_marker (out)
+ * @begin: beginning of the range
+ * @end: end of the range
*
- * Called when no channel users are active by the channel infrastructure.
- * Called with lock_ust_marker() and channel mutex held.
+ * Returns whether a next ust_marker has been found (1) or not (0).
+ * Will return the first ust_marker in the range if the input ust_marker is NULL.
+ * Called with markers mutex held.
*/
-//ust// void ust_marker_compact_event_ids(void)
-//ust// {
-//ust// struct ust_marker_entry *entry;
-//ust// unsigned int i;
-//ust// struct hlist_head *head;
-//ust// struct hlist_node *node;
-//ust// int ret;
-//ust//
-//ust// for (i = 0; i < UST_MARKER_TABLE_SIZE; i++) {
-//ust// head = &ust_marker_table[i];
-//ust// hlist_for_each_entry(entry, node, head, hlist) {
-//ust// ret = ltt_channels_get_index_from_name(entry->channel);
-//ust// WARN_ON(ret < 0);
-//ust// entry->channel_id = ret;
-//ust// ret = _ltt_channels_get_event_id(entry->channel,
-//ust// entry->name);
-//ust// WARN_ON(ret < 0);
-//ust// entry->event_id = ret;
-//ust// }
-//ust// }
-//ust// }
-
-//ust//#ifdef CONFIG_MODULES
+static
+int ust_marker_get_iter_range(struct ust_marker * const **ust_marker,
+ struct ust_marker * const *begin,
+ struct ust_marker * const *end)
+{
+ if (!*ust_marker && begin != end)
+ *ust_marker = begin;
+ while (*ust_marker >= begin && *ust_marker < end) {
+ if (!**ust_marker)
+ (*ust_marker)++; /* skip dummy */
+ else
+ return 1;
+ }
+ return 0;
+}
/*
* Returns 0 if current not found.
* Returns 1 if current found.
+ * Called with markers mutex held.
*/
+static
int lib_get_iter_ust_marker(struct ust_marker_iter *iter)
{
struct ust_marker_lib *iter_lib;
int found = 0;
-//ust// pthread_mutex_lock(&module_mutex);
cds_list_for_each_entry(iter_lib, &ust_marker_libs, list) {
if (iter_lib < iter->lib)
continue;
@@ -1085,35 +1019,10 @@ int lib_get_iter_ust_marker(struct ust_marker_iter *iter)
break;
}
}
-//ust// pthread_mutex_unlock(&module_mutex);
return found;
}
-/**
- * ust_marker_get_iter_range - Get a next ust_marker iterator given a range.
- * @ust_marker: current ust_marker (in), next ust_marker (out)
- * @begin: beginning of the range
- * @end: end of the range
- *
- * Returns whether a next ust_marker has been found (1) or not (0).
- * Will return the first ust_marker in the range if the input ust_marker is NULL.
- */
-int ust_marker_get_iter_range(struct ust_marker * const **ust_marker,
- struct ust_marker * const *begin,
- struct ust_marker * const *end)
-{
- if (!*ust_marker && begin != end)
- *ust_marker = begin;
- while (*ust_marker >= begin && *ust_marker < end) {
- if (!**ust_marker)
- (*ust_marker)++; /* skip dummy */
- else
- return 1;
- }
- return 0;
-}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_get_iter_range);
-
+/* Called with markers mutex held. */
static void ust_marker_get_iter(struct ust_marker_iter *iter)
{
int found = 0;
@@ -1123,12 +1032,13 @@ static void ust_marker_get_iter(struct ust_marker_iter *iter)
ust_marker_iter_reset(iter);
}
+/* Called with markers mutex held. */
void ust_marker_iter_start(struct ust_marker_iter *iter)
{
ust_marker_get_iter(iter);
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_iter_start);
+/* Called with markers mutex held. */
void ust_marker_iter_next(struct ust_marker_iter *iter)
{
iter->ust_marker++;
@@ -1139,147 +1049,18 @@ void ust_marker_iter_next(struct ust_marker_iter *iter)
*/
ust_marker_get_iter(iter);
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_iter_next);
+/* Called with markers mutex held. */
void ust_marker_iter_stop(struct ust_marker_iter *iter)
{
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_iter_stop);
+/* Called with markers mutex held. */
void ust_marker_iter_reset(struct ust_marker_iter *iter)
{
iter->lib = NULL;
iter->ust_marker = NULL;
}
-//ust// EXPORT_SYMBOL_GPL(ust_marker_iter_reset);
-
-#ifdef CONFIG_UST_MARKER_USERSPACE
-/*
- * must be called with current->user_ust_marker_mutex held
- */
-static void free_user_ust_marker(char __user *state, struct cds_hlist_head *head)
-{
- struct user_ust_marker *umark;
- struct cds_hlist_node *pos, *n;
-
- cds_hlist_for_each_entry_safe(umark, pos, n, head, hlist) {
- if (umark->state == state) {
- cds_hlist_del(&umark->hlist);
- free(umark);
- }
- }
-}
-
-/*
- * Update current process.
- * Note that we have to wait a whole scheduler period before we are sure that
- * every running userspace threads have their ust_marker updated.
- * (synchronize_sched() can be used to insure this).
- */
-//ust// void ust_marker_update_process(void)
-//ust// {
-//ust// struct user_ust_marker *umark;
-//ust// struct hlist_node *pos;
-//ust// struct ust_marker_entry *entry;
-//ust//
-//ust// pthread_mutex_lock(&ust_marker_mutex);
-//ust// pthread_mutex_lock(¤t->group_leader->user_ust_marker_mutex);
-//ust// if (strcmp(current->comm, "testprog") == 0)
-//ust// DBG("do update pending for testprog");
-//ust// hlist_for_each_entry(umark, pos,
-//ust// ¤t->group_leader->user_ust_marker, hlist) {
-//ust// DBG("Updating ust_marker %s in %s", umark->name, current->comm);
-//ust// entry = get_ust_marker("userspace", umark->name);
-//ust// if (entry) {
-//ust// if (entry->format &&
-//ust// strcmp(entry->format, umark->format) != 0) {
-//ust// WARN("error, wrong format in process %s",
-//ust// current->comm);
-//ust// break;
-//ust// }
-//ust// if (put_user(!!entry->refcount, umark->state)) {
-//ust// WARN("ust_marker in %s caused a fault",
-//ust// current->comm);
-//ust// break;
-//ust// }
-//ust// } else {
-//ust// if (put_user(0, umark->state)) {
-//ust// WARN("ust_marker in %s caused a fault", current->comm);
-//ust// break;
-//ust// }
-//ust// }
-//ust// }
-//ust// clear_thread_flag(TIF_UST_MARKER_PENDING);
-//ust// pthread_mutex_unlock(¤t->group_leader->user_ust_marker_mutex);
-//ust// pthread_mutex_unlock(&ust_marker_mutex);
-//ust// }
-
-/*
- * Called at process exit and upon do_execve().
- * We assume that when the leader exits, no more references can be done to the
- * leader structure by the other threads.
- */
-void exit_user_ust_marker(struct task_struct *p)
-{
- struct user_ust_marker *umark;
- struct cds_hlist_node *pos, *n;
-
- if (thread_group_leader(p)) {
- pthread_mutex_lock(&ust_marker_mutex);
- pthread_mutex_lock(&p->user_ust_marker_mutex);
- cds_hlist_for_each_entry_safe(umark, pos, n, &p->user_ust_marker,
- hlist)
- free(umark);
- INIT_HLIST_HEAD(&p->user_ust_marker);
- p->user_ust_marker_sequence++;
- pthread_mutex_unlock(&p->user_ust_marker_mutex);
- pthread_mutex_unlock(&ust_marker_mutex);
- }
-}
-
-int is_ust_marker_enabled(const char *channel, const char *name)
-{
- struct ust_marker_entry *entry;
-
- pthread_mutex_lock(&ust_marker_mutex);
- entry = get_ust_marker(channel, name);
- pthread_mutex_unlock(&ust_marker_mutex);
-
- return entry && !!entry->refcount;
-}
-//ust// #endif
-
-int ust_marker_module_notify(struct notifier_block *self,
- unsigned long val, void *data)
-{
- struct module *mod = data;
-
- switch (val) {
- case MODULE_STATE_COMING:
- ust_marker_update_probe_range(mod->ust_marker,
- mod->ust_marker + mod->num_ust_marker);
- break;
- case MODULE_STATE_GOING:
- ust_marker_update_probe_range(mod->ust_marker,
- mod->ust_marker + mod->num_ust_marker);
- break;
- }
- return 0;
-}
-
-struct notifier_block ust_marker_module_nb = {
- .notifier_call = ust_marker_module_notify,
- .priority = 0,
-};
-
-//ust// static int init_ust_marker(void)
-//ust// {
-//ust// return register_module_notifier(&ust_marker_module_nb);
-//ust// }
-//ust// __initcall(init_ust_marker);
-/* TODO: call ust_marker_module_nb() when a library is linked at runtime (dlopen)? */
-
-#endif /* CONFIG_MODULES */
void ltt_dump_ust_marker_state(struct ust_trace *trace)
{
@@ -1319,7 +1100,6 @@ void ltt_dump_ust_marker_state(struct ust_trace *trace)
}
pthread_mutex_unlock(&ust_marker_mutex);
}
-//ust// EXPORT_SYMBOL_GPL(ltt_dump_ust_marker_state);
static void (*new_ust_marker_cb)(struct ust_marker *) = NULL;
@@ -1328,7 +1108,8 @@ void ust_marker_set_new_ust_marker_cb(void (*cb)(struct ust_marker *))
new_ust_marker_cb = cb;
}
-static void new_ust_marker(struct ust_marker * const *start, struct ust_marker * const *end)
+static void new_ust_marker(struct ust_marker * const *start,
+ struct ust_marker * const *end)
{
if (new_ust_marker_cb) {
struct ust_marker * const *m;
@@ -1340,7 +1121,8 @@ static void new_ust_marker(struct ust_marker * const *start, struct ust_marker *
}
}
-int ust_marker_register_lib(struct ust_marker * const *ust_marker_start, int ust_marker_count)
+int ust_marker_register_lib(struct ust_marker * const *ust_marker_start,
+ int ust_marker_count)
{
struct ust_marker_lib *pl, *iter;
@@ -1349,7 +1131,6 @@ int ust_marker_register_lib(struct ust_marker * const *ust_marker_start, int ust
pl->ust_marker_start = ust_marker_start;
pl->ust_marker_count = ust_marker_count;
- /* FIXME: maybe protect this with its own mutex? */
lock_ust_marker();
/*
@@ -1370,7 +1151,7 @@ lib_added:
new_ust_marker(ust_marker_start, ust_marker_start + ust_marker_count);
- /* FIXME: update just the loaded lib */
+ /* TODO: update just the loaded lib */
lib_update_ust_marker();
DBG("just registered a ust_marker section from %p and having %d ust_marker (minus dummy ust_marker)", ust_marker_start, ust_marker_count);
@@ -1382,13 +1163,7 @@ int ust_marker_unregister_lib(struct ust_marker * const *ust_marker_start)
{
struct ust_marker_lib *lib;
- /*FIXME: implement; but before implementing, ust_marker_register_lib must
- have appropriate locking. */
-
lock_ust_marker();
-
- /* FIXME: we should probably take a mutex here on libs */
-//ust// pthread_mutex_lock(&module_mutex);
cds_list_for_each_entry(lib, &ust_marker_libs, list) {
if(lib->ust_marker_start == ust_marker_start) {
struct ust_marker_lib *lib2free = lib;
@@ -1397,7 +1172,6 @@ int ust_marker_unregister_lib(struct ust_marker * const *ust_marker_start)
break;
}
}
-
unlock_ust_marker();
return 0;
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list