X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ust%2Flttng-events.c;h=e618dce62c4f12ecc031a4322c7cb5c556ed3d80;hb=8a5c7efa50f9dce0360611b16323462c77f07321;hp=1981726f4eaac3d40b8bb6a1f1381b2a8a575a81;hpb=8f51c684b1c9fde5d26b24515c03c04e8e4be515;p=lttng-ust.git diff --git a/src/lib/lttng-ust/lttng-events.c b/src/lib/lttng-ust/lttng-events.c index 1981726f..e618dce6 100644 --- a/src/lib/lttng-ust/lttng-events.c +++ b/src/lib/lttng-ust/lttng-events.c @@ -39,17 +39,15 @@ #include "common/ust-fd.h" #include "common/dynamic-type.h" #include "common/ust-context-provider.h" -#include "lttng-ust-uuid.h" #include "common/tracepoint.h" #include "common/strutils.h" #include "lttng-bytecode.h" -#include "lttng-tracer.h" +#include "common/tracer.h" #include "lttng-tracer-core.h" #include "lttng-ust-statedump.h" #include "context-internal.h" #include "lib/lttng-ust/events.h" -#include "wait.h" #include "common/ringbuffer/shm.h" #include "common/ringbuffer/frontend_types.h" #include "common/ringbuffer/frontend.h" @@ -100,6 +98,36 @@ void lttng_ust_format_event_name(const struct lttng_ust_event_desc *desc, strcat(name, desc->event_name); } +static +void lttng_event_enabler_unsync(struct lttng_event_enabler *event_enabler) +{ + cds_list_move(&event_enabler->node, + &event_enabler->chan->parent->session->priv->unsync_enablers_head); +} + +static +void lttng_session_unsync_enablers(struct lttng_ust_session *session) +{ + cds_list_splice(&session->priv->sync_enablers_head, + &session->priv->unsync_enablers_head); + CDS_INIT_LIST_HEAD(&session->priv->sync_enablers_head); +} + +static +void lttng_event_notifier_enabler_unsync(struct lttng_event_notifier_enabler *event_notifier_enabler) +{ + cds_list_move(&event_notifier_enabler->node, + &event_notifier_enabler->group->unsync_enablers_head); +} + +static +void lttng_event_notifier_group_unsync_enablers(struct lttng_event_notifier_group *event_notifier_group) +{ + cds_list_splice(&event_notifier_group->sync_enablers_head, + &event_notifier_group->unsync_enablers_head); + CDS_INIT_LIST_HEAD(&event_notifier_group->sync_enablers_head); +} + /* * Called with ust lock held. */ @@ -121,23 +149,23 @@ int lttng_loglevel_match(int loglevel, int req_loglevel) { if (!has_loglevel) - loglevel = TRACE_DEFAULT; + loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT; switch (req_type) { case LTTNG_UST_ABI_LOGLEVEL_RANGE: if (loglevel <= req_loglevel - || (req_loglevel == -1 && loglevel <= TRACE_DEBUG)) + || (req_loglevel == -1 && loglevel <= LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)) return 1; else return 0; case LTTNG_UST_ABI_LOGLEVEL_SINGLE: if (loglevel == req_loglevel - || (req_loglevel == -1 && loglevel <= TRACE_DEBUG)) + || (req_loglevel == -1 && loglevel <= LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG)) return 1; else return 0; case LTTNG_UST_ABI_LOGLEVEL_ALL: default: - if (loglevel <= TRACE_DEBUG) + if (loglevel <= LTTNG_UST_TRACEPOINT_LOGLEVEL_DEBUG) return 1; else return 0; @@ -169,7 +197,8 @@ struct lttng_ust_session *lttng_session_create(void) CDS_INIT_LIST_HEAD(&session->priv->chan_head); CDS_INIT_LIST_HEAD(&session->priv->events_head); CDS_INIT_LIST_HEAD(&session->priv->enums_head); - CDS_INIT_LIST_HEAD(&session->priv->enablers_head); + CDS_INIT_LIST_HEAD(&session->priv->unsync_enablers_head); + CDS_INIT_LIST_HEAD(&session->priv->sync_enablers_head); for (i = 0; i < LTTNG_UST_EVENT_HT_SIZE; i++) CDS_INIT_HLIST_HEAD(&session->priv->events_ht.table[i]); for (i = 0; i < LTTNG_UST_ENUM_HT_SIZE; i++) @@ -233,7 +262,8 @@ struct lttng_event_notifier_group *lttng_event_notifier_group_create(void) return NULL; } - CDS_INIT_LIST_HEAD(&event_notifier_group->enablers_head); + CDS_INIT_LIST_HEAD(&event_notifier_group->sync_enablers_head); + CDS_INIT_LIST_HEAD(&event_notifier_group->unsync_enablers_head); CDS_INIT_LIST_HEAD(&event_notifier_group->event_notifiers_head); for (i = 0; i < LTTNG_UST_EVENT_NOTIFIER_HT_SIZE; i++) CDS_INIT_HLIST_HEAD(&event_notifier_group->event_notifiers_ht.table[i]); @@ -249,7 +279,7 @@ struct lttng_event_notifier_group *lttng_event_notifier_group_create(void) static void _lttng_channel_unmap(struct lttng_ust_channel_buffer *lttng_chan) { - struct lttng_ust_lib_ring_buffer_channel *chan; + struct lttng_ust_ring_buffer_channel *chan; struct lttng_ust_shm_handle *handle; cds_list_del(<tng_chan->priv->node); @@ -267,14 +297,13 @@ void register_event(struct lttng_ust_event_common *event) { int ret; const struct lttng_ust_event_desc *desc; - char name[LTTNG_UST_ABI_SYM_NAME_LEN]; assert(event->priv->registered == 0); desc = event->priv->desc; - lttng_ust_format_event_name(desc, name); - ret = lttng_ust_tp_probe_register_queue_release(name, - desc->probe_callback, - event, desc->signature); + ret = lttng_ust_tp_probe_register_queue_release(desc->probe_desc->provider_name, + desc->event_name, + desc->tp_class->probe_callback, + event, desc->tp_class->signature); WARN_ON_ONCE(ret); if (!ret) event->priv->registered = 1; @@ -285,13 +314,12 @@ void unregister_event(struct lttng_ust_event_common *event) { int ret; const struct lttng_ust_event_desc *desc; - char name[LTTNG_UST_ABI_SYM_NAME_LEN]; assert(event->priv->registered == 1); desc = event->priv->desc; - lttng_ust_format_event_name(desc, name); - ret = lttng_ust_tp_probe_unregister_queue_release(name, - desc->probe_callback, + ret = lttng_ust_tp_probe_unregister_queue_release(desc->probe_desc->provider_name, + desc->event_name, + desc->tp_class->probe_callback, event); WARN_ON_ONCE(ret); if (!ret) @@ -319,7 +347,10 @@ void lttng_session_destroy(struct lttng_ust_session *session) lttng_ust_urcu_synchronize_rcu(); /* Wait for in-flight events to complete */ lttng_ust_tp_probe_prune_release_queue(); cds_list_for_each_entry_safe(event_enabler, event_tmpenabler, - &session->priv->enablers_head, node) + &session->priv->unsync_enablers_head, node) + lttng_event_enabler_destroy(event_enabler); + cds_list_for_each_entry_safe(event_enabler, event_tmpenabler, + &session->priv->sync_enablers_head, node) lttng_event_enabler_destroy(event_enabler); cds_list_for_each_entry_safe(event_recorder_priv, tmpevent_recorder_priv, &session->priv->events_head, node) @@ -353,7 +384,10 @@ void lttng_event_notifier_group_destroy( lttng_ust_urcu_synchronize_rcu(); cds_list_for_each_entry_safe(notifier_enabler, tmpnotifier_enabler, - &event_notifier_group->enablers_head, node) + &event_notifier_group->sync_enablers_head, node) + lttng_event_notifier_enabler_destroy(notifier_enabler); + cds_list_for_each_entry_safe(notifier_enabler, tmpnotifier_enabler, + &event_notifier_group->unsync_enablers_head, node) lttng_event_notifier_enabler_destroy(notifier_enabler); cds_list_for_each_entry_safe(event_notifier_priv, tmpevent_notifier_priv, @@ -517,7 +551,7 @@ int lttng_create_enum_check(const struct lttng_ust_type_common *type, static int lttng_create_all_event_enums(size_t nr_fields, - const struct lttng_ust_event_field **event_fields, + const struct lttng_ust_event_field * const *event_fields, struct lttng_ust_session *session) { size_t i; @@ -733,7 +767,7 @@ int lttng_event_recorder_create(const struct lttng_ust_event_desc *desc, goto socket_error; } - ret = lttng_create_all_event_enums(desc->nr_fields, desc->fields, + ret = lttng_create_all_event_enums(desc->tp_class->nr_fields, desc->tp_class->fields, session); if (ret < 0) { DBG("Error (%d) adding enum to session", ret); @@ -780,9 +814,9 @@ int lttng_event_recorder_create(const struct lttng_ust_event_desc *desc, event_recorder->parent->priv->desc = desc; if (desc->loglevel) - loglevel = *(*event_recorder->parent->priv->desc->loglevel); + loglevel = *(*desc->loglevel); else - loglevel = TRACE_DEFAULT; + loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT; if (desc->model_emf_uri) uri = *(desc->model_emf_uri); else @@ -797,9 +831,9 @@ int lttng_event_recorder_create(const struct lttng_ust_event_desc *desc, chan->priv->parent.objd, name, loglevel, - desc->signature, - desc->nr_fields, - desc->fields, + desc->tp_class->signature, + desc->tp_class->nr_fields, + desc->tp_class->fields, uri, &event_recorder->priv->id); if (ret < 0) { @@ -1177,12 +1211,12 @@ void _event_enum_destroy(struct lttng_ust_event_common *event) unsigned int i; /* Destroy enums of the current event. */ - for (i = 0; i < event_recorder->parent->priv->desc->nr_fields; i++) { + for (i = 0; i < event_recorder->parent->priv->desc->tp_class->nr_fields; i++) { const struct lttng_ust_enum_desc *enum_desc; const struct lttng_ust_event_field *field; struct lttng_enum *curr_enum; - field = event_recorder->parent->priv->desc->fields[i]; + field = event_recorder->parent->priv->desc->tp_class->fields[i]; switch (field->type->type) { case lttng_ust_type_enum: enum_desc = lttng_ust_get_type_enum(field->type)->desc; @@ -1296,6 +1330,11 @@ int lttng_fix_pending_events(void) struct lttng_ust_session_private *session_priv; cds_list_for_each_entry(session_priv, &sessions, node) { + /* + * New probes have appeared, we need to re-sync all + * enablers. + */ + lttng_session_unsync_enablers(session_priv->pub); lttng_session_lazy_sync_event_enablers(session_priv->pub); } return 0; @@ -1306,6 +1345,11 @@ int lttng_fix_pending_event_notifiers(void) struct lttng_event_notifier_group *event_notifier_group; cds_list_for_each_entry(event_notifier_group, &event_notifier_groups, node) { + /* + * New probes have appeared, we need to re-sync all + * enablers. + */ + lttng_event_notifier_group_unsync_enablers(event_notifier_group); lttng_event_notifier_group_sync_enablers(event_notifier_group); } return 0; @@ -1422,7 +1466,7 @@ struct lttng_event_enabler *lttng_event_enabler_create( event_enabler->chan = chan; /* ctx left NULL */ event_enabler->base.enabled = 0; - cds_list_add(&event_enabler->node, &event_enabler->chan->parent->session->priv->enablers_head); + cds_list_add(&event_enabler->node, &event_enabler->chan->parent->session->priv->unsync_enablers_head); lttng_session_lazy_sync_event_enablers(event_enabler->chan->parent->session); return event_enabler; @@ -1461,7 +1505,7 @@ struct lttng_event_notifier_enabler *lttng_event_notifier_enabler_create( event_notifier_enabler->group = event_notifier_group; cds_list_add(&event_notifier_enabler->node, - &event_notifier_group->enablers_head); + &event_notifier_group->unsync_enablers_head); lttng_event_notifier_group_sync_enablers(event_notifier_group); @@ -1471,6 +1515,7 @@ struct lttng_event_notifier_enabler *lttng_event_notifier_enabler_create( int lttng_event_enabler_enable(struct lttng_event_enabler *event_enabler) { lttng_event_enabler_as_enabler(event_enabler)->enabled = 1; + lttng_event_enabler_unsync(event_enabler); lttng_session_lazy_sync_event_enablers(event_enabler->chan->parent->session); return 0; @@ -1479,6 +1524,7 @@ int lttng_event_enabler_enable(struct lttng_event_enabler *event_enabler) int lttng_event_enabler_disable(struct lttng_event_enabler *event_enabler) { lttng_event_enabler_as_enabler(event_enabler)->enabled = 0; + lttng_event_enabler_unsync(event_enabler); lttng_session_lazy_sync_event_enablers(event_enabler->chan->parent->session); return 0; @@ -1499,7 +1545,7 @@ int lttng_event_enabler_attach_filter_bytecode(struct lttng_event_enabler *event { _lttng_enabler_attach_filter_bytecode( lttng_event_enabler_as_enabler(event_enabler), bytecode); - + lttng_event_enabler_unsync(event_enabler); lttng_session_lazy_sync_event_enablers(event_enabler->chan->parent->session); return 0; } @@ -1519,7 +1565,7 @@ int lttng_event_enabler_attach_exclusion(struct lttng_event_enabler *event_enabl { _lttng_enabler_attach_exclusion( lttng_event_enabler_as_enabler(event_enabler), excluder); - + lttng_event_enabler_unsync(event_enabler); lttng_session_lazy_sync_event_enablers(event_enabler->chan->parent->session); return 0; } @@ -1528,6 +1574,7 @@ int lttng_event_notifier_enabler_enable( struct lttng_event_notifier_enabler *event_notifier_enabler) { lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled = 1; + lttng_event_notifier_enabler_unsync(event_notifier_enabler); lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group); return 0; @@ -1537,6 +1584,7 @@ int lttng_event_notifier_enabler_disable( struct lttng_event_notifier_enabler *event_notifier_enabler) { lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->enabled = 0; + lttng_event_notifier_enabler_unsync(event_notifier_enabler); lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group); return 0; @@ -1549,7 +1597,7 @@ int lttng_event_notifier_enabler_attach_filter_bytecode( _lttng_enabler_attach_filter_bytecode( lttng_event_notifier_enabler_as_enabler(event_notifier_enabler), bytecode); - + lttng_event_notifier_enabler_unsync(event_notifier_enabler); lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group); return 0; } @@ -1565,7 +1613,7 @@ int lttng_event_notifier_enabler_attach_capture_bytecode( /* Take ownership of bytecode */ *bytecode = NULL; event_notifier_enabler->num_captures++; - + lttng_event_notifier_enabler_unsync(event_notifier_enabler); lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group); return 0; } @@ -1577,7 +1625,7 @@ int lttng_event_notifier_enabler_attach_exclusion( _lttng_enabler_attach_exclusion( lttng_event_notifier_enabler_as_enabler(event_notifier_enabler), excluder); - + lttng_event_notifier_enabler_unsync(event_notifier_enabler); lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group); return 0; } @@ -1683,9 +1731,22 @@ void lttng_session_sync_event_enablers(struct lttng_ust_session *session) { struct lttng_event_enabler *event_enabler; struct lttng_ust_event_recorder_private *event_recorder_priv; + struct cds_list_head iter_list; + + /* + * lttng_event_enabler_ref_event_recorders can cause lazy probes + * to add items to the unsync_enablers_head list. Iterate on a + * local copy of that list until it is stable (empty). + */ + do { + CDS_INIT_LIST_HEAD(&iter_list); + cds_list_splice(&session->priv->unsync_enablers_head, &iter_list); + CDS_INIT_LIST_HEAD(&session->priv->unsync_enablers_head); + cds_list_for_each_entry(event_enabler, &iter_list, node) + lttng_event_enabler_ref_event_recorders(event_enabler); + cds_list_splice(&iter_list, &session->priv->sync_enablers_head); + } while (!cds_list_empty(&session->priv->unsync_enablers_head)); - cds_list_for_each_entry(event_enabler, &session->priv->enablers_head, node) - lttng_event_enabler_ref_event_recorders(event_enabler); /* * For each event, if at least one of its enablers is enabled, * and its channel and session transient states are enabled, we @@ -1749,13 +1810,6 @@ void lttng_session_sync_event_enablers(struct lttng_ust_session *session) lttng_ust_tp_probe_prune_release_queue(); } -/* Support for event notifier is introduced by probe provider major version 2. */ -static -bool lttng_ust_probe_supports_event_notifier(const struct lttng_ust_probe_desc *probe_desc) -{ - return probe_desc->major >= 2; -} - static void lttng_create_event_notifier_if_missing( struct lttng_event_notifier_enabler *event_notifier_enabler) @@ -1809,18 +1863,6 @@ void lttng_create_event_notifier_if_missing( if (found) continue; - /* Check that the probe supports event notifiers, else report the error. */ - if (!lttng_ust_probe_supports_event_notifier(probe_desc)) { - ERR("Probe \"%s\" contains event \"%s:%s\" which matches an enabled event notifier, " - "but its version (%u.%u) is too old and does not implement event notifiers. " - "It needs to be recompiled against a newer version of LTTng-UST, otherwise " - "this event will not generate any notification.", - probe_desc->provider_name, - probe_desc->provider_name, desc->event_name, - probe_desc->major, - probe_desc->minor); - continue; - } /* * We need to create a event_notifier for this event probe. */ @@ -1908,9 +1950,22 @@ void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group { struct lttng_event_notifier_enabler *event_notifier_enabler; struct lttng_ust_event_notifier_private *event_notifier_priv; + struct cds_list_head iter_list; - cds_list_for_each_entry(event_notifier_enabler, &event_notifier_group->enablers_head, node) - lttng_event_notifier_enabler_ref_event_notifiers(event_notifier_enabler); + /* + * lttng_event_notifier_enabler_ref_event_notifiers can cause + * lazy probes to add items to the unsync_enablers_head list. + * Iterate on a local copy of that list until it is stable + * (empty). + */ + do { + CDS_INIT_LIST_HEAD(&iter_list); + cds_list_splice(&event_notifier_group->unsync_enablers_head, &iter_list); + CDS_INIT_LIST_HEAD(&event_notifier_group->unsync_enablers_head); + cds_list_for_each_entry(event_notifier_enabler, &iter_list, node) + lttng_event_notifier_enabler_ref_event_notifiers(event_notifier_enabler); + cds_list_splice(&iter_list, &event_notifier_group->sync_enablers_head); + } while (!cds_list_empty(&event_notifier_group->unsync_enablers_head)); /* * For each event_notifier, if at least one of its enablers is enabled, @@ -2000,11 +2055,13 @@ void lttng_session_lazy_sync_event_enablers(struct lttng_ust_session *session) * context (either app context callbacks, or dummy callbacks). */ void lttng_ust_context_set_session_provider(const char *name, - size_t (*get_size)(void *priv, size_t offset), - void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, + size_t (*get_size)(void *priv, struct lttng_ust_probe_ctx *probe_ctx, + size_t offset), + void (*record)(void *priv, struct lttng_ust_probe_ctx *probe_ctx, + struct lttng_ust_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan), - void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), - void *priv) + void (*get_value)(void *priv, struct lttng_ust_probe_ctx *probe_ctx, + struct lttng_ust_ctx_value *value)) { struct lttng_ust_session_private *session_priv; @@ -2014,18 +2071,18 @@ void lttng_ust_context_set_session_provider(const char *name, int ret; ret = lttng_ust_context_set_provider_rcu(&session_priv->ctx, - name, get_size, record, get_value, priv); + name, get_size, record, get_value); if (ret) abort(); cds_list_for_each_entry(chan, &session_priv->chan_head, node) { ret = lttng_ust_context_set_provider_rcu(&chan->ctx, - name, get_size, record, get_value, priv); + name, get_size, record, get_value); if (ret) abort(); } cds_list_for_each_entry(event_recorder_priv, &session_priv->events_head, node) { ret = lttng_ust_context_set_provider_rcu(&event_recorder_priv->ctx, - name, get_size, record, get_value, priv); + name, get_size, record, get_value); if (ret) abort(); } @@ -2040,11 +2097,13 @@ void lttng_ust_context_set_session_provider(const char *name, * context (either app context callbacks, or dummy callbacks). */ void lttng_ust_context_set_event_notifier_group_provider(const char *name, - size_t (*get_size)(void *priv, size_t offset), - void (*record)(void *priv, struct lttng_ust_lib_ring_buffer_ctx *ctx, + size_t (*get_size)(void *priv, struct lttng_ust_probe_ctx *probe_ctx, + size_t offset), + void (*record)(void *priv, struct lttng_ust_probe_ctx *probe_ctx, + struct lttng_ust_ring_buffer_ctx *ctx, struct lttng_ust_channel_buffer *chan), - void (*get_value)(void *priv, struct lttng_ust_ctx_value *value), - void *priv) + void (*get_value)(void *priv, struct lttng_ust_probe_ctx *probe_ctx, + struct lttng_ust_ctx_value *value)) { struct lttng_event_notifier_group *event_notifier_group; @@ -2053,7 +2112,7 @@ void lttng_ust_context_set_event_notifier_group_provider(const char *name, ret = lttng_ust_context_set_provider_rcu( &event_notifier_group->ctx, - name, get_size, record, get_value, priv); + name, get_size, record, get_value); if (ret) abort(); }