X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Flttng-events.c;h=012f2245a353f4b7c43c689985b30628d65063d1;hb=a101fa100885861be33fab3966db2c5136815724;hp=54d7a0d0cd9132c5178fcde503bdbb761712c9ca;hpb=0b365677b4b159fa9aa2b98eb19f10f4a762fbe8;p=deliverable%2Flttng-modules.git diff --git a/src/lttng-events.c b/src/lttng-events.c index 54d7a0d0..012f2245 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -52,6 +52,7 @@ static LIST_HEAD(sessions); static LIST_HEAD(event_notifier_groups); static LIST_HEAD(lttng_transport_list); +static LIST_HEAD(lttng_counter_transport_list); /* * Protect the sessions and metadata caches. */ @@ -759,6 +760,18 @@ void _lttng_metadata_channel_hangup(struct lttng_metadata_stream *stream) wake_up_interruptible(&stream->read_wait); } +static +struct lttng_counter_transport *lttng_counter_transport_find(const char *name) +{ + struct lttng_counter_transport *transport; + + list_for_each_entry(transport, <tng_counter_transport_list, node) { + if (!strcmp(transport->name, name)) + return transport; + } + return NULL; +} + /* * Supports event creation while tracing session is active. * Needs to be called with sessions mutex held. @@ -1048,11 +1061,13 @@ struct lttng_event_notifier *_lttng_event_notifier_create( event_notifier->group = event_notifier_group; event_notifier->user_token = token; + event_notifier->num_captures = 0; event_notifier->filter = filter; event_notifier->instrumentation = itype; event_notifier->evtype = LTTNG_TYPE_EVENT; event_notifier->send_notification = lttng_event_notifier_notification_send; INIT_LIST_HEAD(&event_notifier->filter_bytecode_runtime_head); + INIT_LIST_HEAD(&event_notifier->capture_bytecode_runtime_head); INIT_LIST_HEAD(&event_notifier->enablers_ref_head); switch (itype) { @@ -2032,7 +2047,7 @@ int lttng_event_enabler_ref_events(struct lttng_event_enabler *event_enabler) lttng_enabler_link_bytecode(event->desc, lttng_static_ctx, &event->filter_bytecode_runtime_head, - lttng_event_enabler_as_enabler(event_enabler)); + <tng_event_enabler_as_enabler(event_enabler)->filter_bytecode_head); /* TODO: merge event context. */ } @@ -2119,7 +2134,14 @@ int lttng_event_notifier_enabler_ref_event_notifiers( */ lttng_enabler_link_bytecode(event_notifier->desc, lttng_static_ctx, &event_notifier->filter_bytecode_runtime_head, - lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)); + <tng_event_notifier_enabler_as_enabler(event_notifier_enabler)->filter_bytecode_head); + + /* Link capture bytecodes if not linked yet. */ + lttng_enabler_link_bytecode(event_notifier->desc, + lttng_static_ctx, &event_notifier->capture_bytecode_runtime_head, + &event_notifier_enabler->capture_bytecode_head); + + event_notifier->num_captures = event_notifier_enabler->num_captures; } return 0; } @@ -2225,7 +2247,7 @@ int lttng_enabler_attach_filter_bytecode(struct lttng_enabler *enabler, ret = get_user(bytecode_len, &bytecode->len); if (ret) return ret; - bytecode_node = kzalloc(sizeof(*bytecode_node) + bytecode_len, + bytecode_node = lttng_kvzalloc(sizeof(*bytecode_node) + bytecode_len, GFP_KERNEL); if (!bytecode_node) return -ENOMEM; @@ -2243,7 +2265,7 @@ int lttng_enabler_attach_filter_bytecode(struct lttng_enabler *enabler, return 0; error_free: - kfree(bytecode_node); + lttng_kvfree(bytecode_node); return ret; } @@ -2289,7 +2311,7 @@ void lttng_enabler_destroy(struct lttng_enabler *enabler) /* Destroy filter bytecode */ list_for_each_entry_safe(filter_node, tmp_filter_node, &enabler->filter_bytecode_head, node) { - kfree(filter_node); + lttng_kvfree(filter_node); } } @@ -2318,6 +2340,9 @@ struct lttng_event_notifier_enabler *lttng_event_notifier_enabler_create( event_notifier_enabler->base.format_type = format_type; INIT_LIST_HEAD(&event_notifier_enabler->base.filter_bytecode_head); + INIT_LIST_HEAD(&event_notifier_enabler->capture_bytecode_head); + + event_notifier_enabler->num_captures = 0; memcpy(&event_notifier_enabler->base.event_param, &event_notifier_param->event, sizeof(event_notifier_enabler->base.event_param)); @@ -2375,6 +2400,48 @@ error: return ret; } +int lttng_event_notifier_enabler_attach_capture_bytecode( + struct lttng_event_notifier_enabler *event_notifier_enabler, + struct lttng_kernel_capture_bytecode __user *bytecode) +{ + struct lttng_bytecode_node *bytecode_node; + struct lttng_enabler *enabler = + lttng_event_notifier_enabler_as_enabler(event_notifier_enabler); + uint32_t bytecode_len; + int ret; + + ret = get_user(bytecode_len, &bytecode->len); + if (ret) + return ret; + + bytecode_node = lttng_kvzalloc(sizeof(*bytecode_node) + bytecode_len, + GFP_KERNEL); + if (!bytecode_node) + return -ENOMEM; + + ret = copy_from_user(&bytecode_node->bc, bytecode, + sizeof(*bytecode) + bytecode_len); + if (ret) + goto error_free; + + bytecode_node->type = LTTNG_BYTECODE_NODE_TYPE_CAPTURE; + bytecode_node->enabler = enabler; + + /* Enforce length based on allocated size */ + bytecode_node->bc.len = bytecode_len; + list_add_tail(&bytecode_node->node, &event_notifier_enabler->capture_bytecode_head); + + event_notifier_enabler->num_captures++; + + lttng_event_notifier_group_sync_enablers(event_notifier_enabler->group); + goto end; + +error_free: + lttng_kvfree(bytecode_node); +end: + return ret; +} + int lttng_event_notifier_add_callsite(struct lttng_event_notifier *event_notifier, struct lttng_kernel_event_callsite __user *callsite) { @@ -2565,6 +2632,11 @@ void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group list_for_each_entry(runtime, &event_notifier->filter_bytecode_runtime_head, node) lttng_bytecode_filter_sync_state(runtime); + + /* Enable captures */ + list_for_each_entry(runtime, + &event_notifier->capture_bytecode_runtime_head, node) + lttng_bytecode_capture_sync_state(runtime); } } @@ -3819,6 +3891,29 @@ void lttng_transport_unregister(struct lttng_transport *transport) } EXPORT_SYMBOL_GPL(lttng_transport_unregister); +void lttng_counter_transport_register(struct lttng_counter_transport *transport) +{ + /* + * Make sure no page fault can be triggered by the module about to be + * registered. We deal with this here so we don't have to call + * vmalloc_sync_mappings() in each module's init. + */ + wrapper_vmalloc_sync_mappings(); + + mutex_lock(&sessions_mutex); + list_add_tail(&transport->node, <tng_counter_transport_list); + mutex_unlock(&sessions_mutex); +} +EXPORT_SYMBOL_GPL(lttng_counter_transport_register); + +void lttng_counter_transport_unregister(struct lttng_counter_transport *transport) +{ + mutex_lock(&sessions_mutex); + list_del(&transport->node); + mutex_unlock(&sessions_mutex); +} +EXPORT_SYMBOL_GPL(lttng_counter_transport_unregister); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)) enum cpuhp_state lttng_hp_prepare;