Refactoring and fix: bytecode ABI
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 19 Mar 2021 04:03:17 +0000 (00:03 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 19 Mar 2021 15:27:23 +0000 (11:27 -0400)
Introduce an "event filter" callback to be called by the instrumentation
probe, and move the bytecode list into private data structures.

This will allow much more freedom in choosing how bytecodes are combined
both in terms of logic (OR vs AND) and implementation (jits).

Currently, we keep callbacks internally as well for each bytecode
evaluation, but nothing prevents to change how this works in the future
to improve performance now that this is all private.

For filters, we add the following fields to struct lttng_ust_event_common:

       int eval_filter;                                /* Need to evaluate filters */
       int (*run_filter)(struct lttng_ust_event_common *event,
               const char *stack_data,
               void *filter_ctx);

"eval_filter" is a state indicating whether the filter should be
evaluated at all. It combines internal knowledge of whether the filter
bytecode list is empty, and whether there are enablers without filter
bytecode attached to the event.

For captures, a new struct lttng_ust_notification_ctx is introduced,
which is to be used as additional "context" to the notification_send()
callback. This allows passing the "eval_capture" state from the probe
to the notification callback, and fixes a bug where a sequence of:

- create notification enabler,
- enable notification enabler,
- add capture to enabler,

where a tracepoint runs concurrently with add capture happens to do a
first capture list_empty check which skips the stack preparation,
whereas the second capture list_empty check within the notification
callback finds a capture entry, and thus attempts to use an
uninitialized stack. The notification callback is also modified to use
an RCU-aware list traversal.

For captures, the following field is added to struct lttng_ust_event_notifier:

       int eval_capture;                               /* Need to evaluate capture */

which is to be read once by the probe and its state saved and used
thorough the entire probe execution.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Iae70c5e7924f14b38e14676368cf2516951218ee

include/lttng/ust-events.h
include/lttng/ust-tracepoint-event.h
liblttng-ust/event-notifier-notification.c
liblttng-ust/lttng-bytecode-interpreter.c
liblttng-ust/lttng-bytecode-specialize.c
liblttng-ust/lttng-bytecode-validator.c
liblttng-ust/lttng-bytecode.c
liblttng-ust/lttng-bytecode.h
liblttng-ust/lttng-events.c
liblttng-ust/lttng-tracer-core.h
liblttng-ust/ust-events-internal.h

index 58a0baf4a5c92713d4658c58589010c828128f75..e8e4bf2cac12d254bd11ae884847c2f4367bcf64 100644 (file)
@@ -296,60 +296,6 @@ struct lttng_ust_probe_desc {
 
 /* Data structures used by the tracer. */
 
-/*
- * Bytecode interpreter return value.
- */
-enum lttng_ust_bytecode_interpreter_ret {
-       LTTNG_UST_BYTECODE_INTERPRETER_ERROR = -1,
-       LTTNG_UST_BYTECODE_INTERPRETER_OK = 0,
-};
-
-struct lttng_interpreter_output;
-struct lttng_ust_bytecode_runtime_private;
-
-enum lttng_ust_bytecode_filter_result {
-       LTTNG_UST_BYTECODE_FILTER_ACCEPT = 0,
-       LTTNG_UST_BYTECODE_FILTER_REJECT = 1,
-};
-
-/*
- * IMPORTANT: this structure is part of the ABI between the probe and
- * UST. Fields need to be only added at the end, never reordered, never
- * removed.
- *
- * The field @struct_size should be used to determine the size of the
- * structure. It should be queried before using additional fields added
- * at the end of the structure.
- */
-struct lttng_ust_bytecode_filter_ctx {
-       uint32_t struct_size;                   /* Size of this structure. */
-
-       enum lttng_ust_bytecode_filter_result result;
-
-       /* End of base ABI. Fields below should be used after checking struct_size. */
-};
-
-/*
- * IMPORTANT: this structure is part of the ABI between the probe and
- * UST. Fields need to be only added at the end, never reordered, never
- * removed.
- *
- * The field @struct_size should be used to determine the size of the
- * structure. It should be queried before using additional fields added
- * at the end of the structure.
- */
-struct lttng_ust_bytecode_runtime {
-       uint32_t struct_size;                   /* Size of this structure. */
-
-       struct lttng_ust_bytecode_runtime_private *priv;
-       int (*interpreter_func)(struct lttng_ust_bytecode_runtime *bytecode_runtime,
-                       const char *interpreter_stack_data,
-                       void *ctx);
-       struct cds_list_head node;      /* list of bytecode runtime in event */
-
-       /* End of base ABI. Fields below should be used after checking struct_size. */
-};
-
 /*
  * lttng_event structure is referred to by the tracing fast path. It
  * must be kept small.
@@ -367,6 +313,14 @@ enum lttng_ust_event_type {
        LTTNG_UST_EVENT_TYPE_NOTIFIER = 1,
 };
 
+/*
+ * Result of the run_filter() callback.
+ */
+enum lttng_ust_event_filter_result {
+       LTTNG_UST_EVENT_FILTER_ACCEPT = 0,
+       LTTNG_UST_EVENT_FILTER_REJECT = 1,
+};
+
 /*
  * IMPORTANT: this structure is part of the ABI between the probe and
  * UST. Fields need to be only added at the end, never reordered, never
@@ -391,9 +345,10 @@ struct lttng_ust_event_common {
        void *child;                                    /* Pointer to child, for inheritance by aggregation. */
 
        int enabled;
-       int has_enablers_without_bytecode;
-       /* list of struct lttng_ust_bytecode_runtime, sorted by seqnum */
-       struct cds_list_head filter_bytecode_runtime_head;
+       int eval_filter;                                /* Need to evaluate filters */
+       int (*run_filter)(struct lttng_ust_event_common *event,
+               const char *stack_data,
+               void *filter_ctx);
 
        /* End of base ABI. Fields below should be used after checking struct_size. */
 };
@@ -426,6 +381,22 @@ struct lttng_ust_event_recorder {
        /* End of base ABI. Fields below should be used after checking struct_size. */
 };
 
+/*
+ * IMPORTANT: this structure is part of the ABI between the probe and
+ * UST. Fields need to be only added at the end, never reordered, never
+ * removed.
+ *
+ * The field @struct_size should be used to determine the size of the
+ * structure. It should be queried before using additional fields added
+ * at the end of the structure.
+ */
+struct lttng_ust_notification_ctx {
+       uint32_t struct_size;           /* Size of this structure. */
+       int eval_capture;               /* Capture evaluation available. */
+
+       /* End of base ABI. Fields below should be used after checking struct_size. */
+};
+
 struct lttng_ust_event_notifier_private;
 
 /*
@@ -448,9 +419,10 @@ struct lttng_ust_event_notifier {
        struct lttng_ust_event_common *parent;          /* Inheritance by aggregation. */
        struct lttng_ust_event_notifier_private *priv;  /* Private event notifier interface */
 
+       int eval_capture;                               /* Need to evaluate capture */
        void (*notification_send)(struct lttng_ust_event_notifier *event_notifier,
-               const char *stack_data);
-       struct cds_list_head capture_bytecode_runtime_head;
+               const char *stack_data,
+               struct lttng_ust_notification_ctx *notif_ctx);
 
        /* End of base ABI. Fields below should be used after checking struct_size. */
 };
index 4fc1ea91aa8c6f49abe3e5871221d4db5110f0af..fc327a689d1b777ce57a4f5e26d6faed69e07d2b 100644 (file)
@@ -796,6 +796,7 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))           \
                char __interpreter_stack_data[2 * sizeof(unsigned long) * __num_fields]; \
        } __stackvar;                                                         \
        int __ret;                                                            \
+       bool __interpreter_stack_prepared = false;                            \
                                                                              \
        if (0)                                                                \
                (void) __dynamic_len_idx;       /* don't warn if unused */    \
@@ -821,24 +822,12 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))         \
                return;                                                       \
        if (caa_unlikely(!TP_RCU_LINK_TEST()))                                \
                return;                                                       \
-       if (caa_unlikely(!cds_list_empty(&__event->filter_bytecode_runtime_head))) { \
-               struct lttng_ust_bytecode_runtime *__filter_bc_runtime;       \
-               int __filter_record = __event->has_enablers_without_bytecode; \
-               struct lttng_ust_bytecode_filter_ctx filter_ctx;              \
-                                                                             \
-               filter_ctx.struct_size = sizeof(struct lttng_ust_bytecode_filter_ctx); \
+       if (caa_unlikely(CMM_ACCESS_ONCE(__event->eval_filter))) { \
                __event_prepare_interpreter_stack__##_provider##___##_name(__stackvar.__interpreter_stack_data, \
                        _TP_ARGS_DATA_VAR(_args));                            \
-               tp_list_for_each_entry_rcu(__filter_bc_runtime, &__event->filter_bytecode_runtime_head, node) { \
-                       if (caa_likely(__filter_bc_runtime->interpreter_func(__filter_bc_runtime, \
-                               __stackvar.__interpreter_stack_data, &filter_ctx) == LTTNG_UST_BYTECODE_INTERPRETER_OK)) { \
-                               if (caa_unlikely(filter_ctx.result == LTTNG_UST_BYTECODE_FILTER_ACCEPT)) { \
-                                       __filter_record = 1;                  \
-                                       break;                                \
-                               }                                             \
-                       }                                                     \
-               }                                                             \
-               if (caa_likely(!__filter_record))                             \
+               __interpreter_stack_prepared = true;                          \
+               if (caa_likely(__event->run_filter(__event, \
+                               __stackvar.__interpreter_stack_data, NULL) != LTTNG_UST_EVENT_FILTER_ACCEPT)) \
                        return;                                               \
        }                                                                     \
        switch (__event->type) {                                              \
@@ -869,13 +858,18 @@ void __event_probe__##_provider##___##_name(_TP_ARGS_DATA_PROTO(_args))         \
        case LTTNG_UST_EVENT_TYPE_NOTIFIER:                                   \
        {                                                                     \
                struct lttng_ust_event_notifier *__event_notifier = (struct lttng_ust_event_notifier *) __event->child; \
+               struct lttng_ust_notification_ctx __notif_ctx;                \
+                                                                             \
+               __notif_ctx.struct_size = sizeof(struct lttng_ust_notification_ctx); \
+               __notif_ctx.eval_capture = CMM_ACCESS_ONCE(__event_notifier->eval_capture); \
                                                                              \
-               if (caa_unlikely(!cds_list_empty(&__event_notifier->capture_bytecode_runtime_head))) \
+               if (caa_unlikely(!__interpreter_stack_prepared && __notif_ctx.eval_capture)) \
                        __event_prepare_interpreter_stack__##_provider##___##_name(__stackvar.__interpreter_stack_data, \
                                _TP_ARGS_DATA_VAR(_args));                    \
                                                                              \
                __event_notifier->notification_send(__event_notifier,         \
-                               __stackvar.__interpreter_stack_data);         \
+                               __stackvar.__interpreter_stack_data,          \
+                               &__notif_ctx);                                \
                break;                                                        \
        }                                                                     \
        }                                                                     \
index b4c666aa560364e064999bbb40ba027e7c131b7a..40ad731e856b7e200ec4bf9b5b2abb35b7d33afa 100644 (file)
@@ -10,6 +10,7 @@
 #include <errno.h>
 #include <lttng/ust-endian.h>
 #include <usterr-signal-safe.h>
+#include <urcu/rculist.h>
 
 #include "ust-events-internal.h"
 #include "../libmsgpack/msgpack.h"
@@ -357,7 +358,8 @@ void notification_send(struct lttng_event_notifier_notification *notif,
 
 void lttng_event_notifier_notification_send(
                struct lttng_ust_event_notifier *event_notifier,
-               const char *stack_data)
+               const char *stack_data,
+               struct lttng_ust_notification_ctx *notif_ctx)
 {
        /*
         * This function is called from the probe, we must do dynamic
@@ -367,7 +369,7 @@ void lttng_event_notifier_notification_send(
 
        notification_init(&notif, event_notifier);
 
-       if (caa_unlikely(!cds_list_empty(&event_notifier->capture_bytecode_runtime_head))) {
+       if (caa_unlikely(notif_ctx->eval_capture)) {
                struct lttng_ust_bytecode_runtime *capture_bc_runtime;
 
                /*
@@ -376,8 +378,8 @@ void lttng_event_notifier_notification_send(
                 * `output` parameter to the capture buffer. If the interpreter
                 * fails, append an empty capture to the buffer.
                 */
-               cds_list_for_each_entry(capture_bc_runtime,
-                               &event_notifier->capture_bytecode_runtime_head, node) {
+               cds_list_for_each_entry_rcu(capture_bc_runtime,
+                               &event_notifier->priv->capture_bytecode_runtime_head, node) {
                        struct lttng_interpreter_output output;
 
                        if (capture_bc_runtime->interpreter_func(capture_bc_runtime,
index c329415bca70978ed6cf53de6ef8ab67e6ae1bc0..a384d61f068c92d2d2e4d0b54eb42ddc42f4fe36 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdint.h>
 
 #include <lttng/urcu/pointer.h>
+#include <urcu/rculist.h>
 #include <lttng/ust-endian.h>
 #include <lttng/ust-events.h>
 #include "ust-events-internal.h"
@@ -711,7 +712,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                void *caller_ctx)
 {
        struct bytecode_runtime *bytecode = caa_container_of(ust_bytecode, struct bytecode_runtime, p);
-       struct lttng_ust_ctx *ctx = lttng_ust_rcu_dereference(*ust_bytecode->priv->pctx);
+       struct lttng_ust_ctx *ctx = lttng_ust_rcu_dereference(*ust_bytecode->pctx);
        void *pc, *next_pc, *start_pc;
        int ret = -EINVAL, retval = 0;
        struct estack _stack;
@@ -879,7 +880,7 @@ int lttng_bytecode_interpret(struct lttng_ust_bytecode_runtime *ust_bytecode,
                        case REG_DOUBLE:
                        case REG_STRING:
                        case REG_PTR:
-                               if (ust_bytecode->priv->type != LTTNG_UST_BYTECODE_TYPE_CAPTURE) {
+                               if (ust_bytecode->type != LTTNG_UST_BYTECODE_TYPE_CAPTURE) {
                                        ret = -EINVAL;
                                        goto end;
                                }
@@ -2480,7 +2481,7 @@ end:
                return LTTNG_UST_BYTECODE_INTERPRETER_ERROR;
 
        /* Prepare output. */
-       switch (ust_bytecode->priv->type) {
+       switch (ust_bytecode->type) {
        case LTTNG_UST_BYTECODE_TYPE_FILTER:
        {
                struct lttng_ust_bytecode_filter_ctx *filter_ctx =
@@ -2505,6 +2506,33 @@ end:
                return LTTNG_UST_BYTECODE_INTERPRETER_OK;
 }
 
+/*
+ * Return LTTNG_UST_EVENT_FILTER_ACCEPT or LTTNG_UST_EVENT_FILTER_REJECT.
+ */
+int lttng_ust_interpret_event_filter(struct lttng_ust_event_common *event,
+               const char *interpreter_stack_data,
+               void *event_filter_ctx)
+{
+       struct lttng_ust_bytecode_runtime *filter_bc_runtime;
+       struct cds_list_head *filter_bytecode_runtime_head = &event->priv->filter_bytecode_runtime_head;
+       struct lttng_ust_bytecode_filter_ctx bytecode_filter_ctx;
+       bool filter_record = false;
+
+       cds_list_for_each_entry_rcu(filter_bc_runtime, filter_bytecode_runtime_head, node) {
+               if (caa_likely(filter_bc_runtime->interpreter_func(filter_bc_runtime,
+                               interpreter_stack_data, &bytecode_filter_ctx) == LTTNG_UST_BYTECODE_INTERPRETER_OK)) {
+                       if (caa_unlikely(bytecode_filter_ctx.result == LTTNG_UST_BYTECODE_FILTER_ACCEPT)) {
+                               filter_record = true;
+                               break;
+                       }
+               }
+       }
+       if (filter_record)
+               return LTTNG_UST_EVENT_FILTER_ACCEPT;
+       else
+               return LTTNG_UST_EVENT_FILTER_REJECT;
+}
+
 #undef START_OP
 #undef OP
 #undef PO
index 28b0ea721381eb63c70f602c22184edcef4a779c..065c0eb24a16ae848bfa34b921a3ad83e80c17e9 100644 (file)
@@ -374,7 +374,7 @@ static int specialize_context_lookup_name(struct lttng_ust_ctx *ctx,
        const char *name;
 
        offset = ((struct get_symbol *) insn->data)->offset;
-       name = bytecode->p.priv->bc->bc.data + bytecode->p.priv->bc->bc.reloc_offset + offset;
+       name = bytecode->p.bc->bc.data + bytecode->p.bc->bc.reloc_offset + offset;
        return lttng_get_context_index(ctx, name);
 }
 
@@ -503,7 +503,7 @@ static int specialize_app_context_lookup(struct lttng_ust_ctx **pctx,
        ssize_t data_offset;
 
        offset = ((struct get_symbol *) insn->data)->offset;
-       orig_name = runtime->p.priv->bc->bc.data + runtime->p.priv->bc->bc.reloc_offset + offset;
+       orig_name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
        name = zmalloc(strlen(orig_name) + strlen("$app.") + 1);
        if (!name) {
                ret = -ENOMEM;
@@ -564,7 +564,7 @@ static int specialize_payload_lookup(struct lttng_ust_event_desc *event_desc,
 
        nr_fields = event_desc->nr_fields;
        offset = ((struct get_symbol *) insn->data)->offset;
-       name = runtime->p.priv->bc->bc.data + runtime->p.priv->bc->bc.reloc_offset + offset;
+       name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
        for (i = 0; i < nr_fields; i++) {
                field = event_desc->fields[i];
                if (field->nofilter) {
@@ -631,7 +631,7 @@ int lttng_bytecode_specialize(struct lttng_ust_event_desc *event_desc,
        int ret = -EINVAL;
        struct vstack _stack;
        struct vstack *stack = &_stack;
-       struct lttng_ust_ctx **pctx = bytecode->p.priv->pctx;
+       struct lttng_ust_ctx **pctx = bytecode->p.pctx;
 
        vstack_init(stack);
 
index ea86c5e75126b8e517e92893bb5ee87f26e7ba77..68b9e008a111144aa6fb77ddf2c908dbc5b7d911 100644 (file)
@@ -256,11 +256,11 @@ int validate_get_symbol(struct bytecode_runtime *bytecode,
        const char *str, *str_limit;
        size_t len_limit;
 
-       if (sym->offset >= bytecode->p.priv->bc->bc.len - bytecode->p.priv->bc->bc.reloc_offset)
+       if (sym->offset >= bytecode->p.bc->bc.len - bytecode->p.bc->bc.reloc_offset)
                return -EINVAL;
 
-       str = bytecode->p.priv->bc->bc.data + bytecode->p.priv->bc->bc.reloc_offset + sym->offset;
-       str_limit = bytecode->p.priv->bc->bc.data + bytecode->p.priv->bc->bc.len;
+       str = bytecode->p.bc->bc.data + bytecode->p.bc->bc.reloc_offset + sym->offset;
+       str_limit = bytecode->p.bc->bc.data + bytecode->p.bc->bc.len;
        len_limit = str_limit - str;
        if (strnlen(str, len_limit) == len_limit)
                return -EINVAL;
index 6ce5e54a39827bf385f5491169a630712a0650fe..3fe50c36e707599d79b6e13b41de4fe5444e0bde 100644 (file)
@@ -276,7 +276,7 @@ int apply_context_reloc(struct bytecode_runtime *runtime,
        struct load_op *op;
        struct lttng_ust_ctx_field *ctx_field;
        int idx;
-       struct lttng_ust_ctx **pctx = runtime->p.priv->pctx;
+       struct lttng_ust_ctx **pctx = runtime->p.pctx;
 
        dbg_printf("Apply context reloc: %u %s\n", reloc_offset, context_name);
 
@@ -385,7 +385,7 @@ int bytecode_is_linked(struct lttng_ust_bytecode_node *bytecode,
        struct lttng_ust_bytecode_runtime *bc_runtime;
 
        cds_list_for_each_entry(bc_runtime, bytecode_runtime_head, node) {
-               if (bc_runtime->priv->bc == bytecode)
+               if (bc_runtime->bc == bytecode)
                        return 1;
        }
        return 0;
@@ -404,7 +404,6 @@ int link_bytecode(struct lttng_ust_event_desc *event_desc,
 {
        int ret, offset, next_offset;
        struct bytecode_runtime *runtime = NULL;
-       struct lttng_ust_bytecode_runtime_private *runtime_priv = NULL;
        size_t runtime_alloc_len;
 
        if (!bytecode)
@@ -422,19 +421,9 @@ int link_bytecode(struct lttng_ust_event_desc *event_desc,
                ret = -ENOMEM;
                goto alloc_error;
        }
-       runtime_priv = zmalloc(sizeof(struct lttng_ust_bytecode_runtime_private));
-       if (!runtime_priv) {
-               free(runtime);
-               runtime = NULL;
-               ret = -ENOMEM;
-               goto alloc_error;
-       }
-       runtime->p.priv = runtime_priv;
-       runtime->p.struct_size = sizeof(struct lttng_ust_bytecode_runtime);
-       runtime_priv->pub = runtime;
-       runtime_priv->type = bytecode->type;
-       runtime_priv->bc = bytecode;
-       runtime_priv->pctx = ctx;
+       runtime->p.type = bytecode->type;
+       runtime->p.bc = bytecode;
+       runtime->p.pctx = ctx;
        runtime->len = bytecode->bc.reloc_offset;
        /* copy original bytecode */
        memcpy(runtime->code, bytecode->bc.data, runtime->len);
@@ -468,14 +457,14 @@ int link_bytecode(struct lttng_ust_event_desc *event_desc,
        }
 
        runtime->p.interpreter_func = lttng_bytecode_interpret;
-       runtime->p.priv->link_failed = 0;
+       runtime->p.link_failed = 0;
        cds_list_add_rcu(&runtime->p.node, insert_loc);
        dbg_printf("Linking successful.\n");
        return 0;
 
 link_error:
        runtime->p.interpreter_func = lttng_bytecode_interpret_error;
-       runtime_priv->link_failed = 1;
+       runtime->p.link_failed = 1;
        cds_list_add_rcu(&runtime->p.node, insert_loc);
 alloc_error:
        dbg_printf("Linking failed.\n");
@@ -484,9 +473,9 @@ alloc_error:
 
 void lttng_bytecode_sync_state(struct lttng_ust_bytecode_runtime *runtime)
 {
-       struct lttng_ust_bytecode_node *bc = runtime->priv->bc;
+       struct lttng_ust_bytecode_node *bc = runtime->bc;
 
-       if (!bc->enabler->enabled || runtime->priv->link_failed)
+       if (!bc->enabler->enabled || runtime->link_failed)
                runtime->interpreter_func = lttng_bytecode_interpret_error;
        else
                runtime->interpreter_func = lttng_bytecode_interpret;
@@ -520,7 +509,7 @@ void lttng_enabler_link_bytecode(struct lttng_ust_event_desc *event_desc,
                 * linked with the instance.
                 */
                cds_list_for_each_entry(runtime, instance_bytecode_head, node) {
-                       if (runtime->priv->bc == enabler_bc) {
+                       if (runtime->bc == enabler_bc) {
                                found = 1;
                                break;
                        }
@@ -540,7 +529,7 @@ void lttng_enabler_link_bytecode(struct lttng_ust_event_desc *event_desc,
                 */
                cds_list_for_each_entry_reverse(runtime,
                                instance_bytecode_head, node) {
-                       if (runtime->priv->bc->bc.seqnum <= enabler_bc->bc.seqnum) {
+                       if (runtime->bc->bc.seqnum <= enabler_bc->bc.seqnum) {
                                /* insert here */
                                insert_loc = &runtime->node;
                                goto add_within;
@@ -576,12 +565,11 @@ void free_filter_runtime(struct cds_list_head *bytecode_runtime_head)
        cds_list_for_each_entry_safe(runtime, tmp, bytecode_runtime_head,
                        p.node) {
                free(runtime->data);
-               free(runtime->p.priv);
                free(runtime);
        }
 }
 
 void lttng_free_event_filter_runtime(struct lttng_ust_event_common *event)
 {
-       free_filter_runtime(&event->filter_bytecode_runtime_head);
+       free_filter_runtime(&event->priv->filter_bytecode_runtime_head);
 }
index 220e8d03a48ef1cef9fa2a103bdb6dfe0cb99647..846d11a42c4f82852b1e3467dad0c6be33a1f556 100644 (file)
@@ -23,6 +23,7 @@
 #include <limits.h>
 #include <usterr-signal-safe.h>
 #include "bytecode.h"
+#include "ust-events-internal.h"
 
 /* Interpreter stack length, in number of entries */
 #define INTERPRETER_STACK_LEN  10      /* includes 2 dummy */
index 9dc69ba9322d836757caa087c6bbfb43f0e33372..9c65dc4544ffb85fb94bf6552ff7b851c063b2ee 100644 (file)
@@ -750,9 +750,10 @@ int lttng_event_recorder_create(struct lttng_ust_event_desc *desc,
        event_recorder->chan = chan;
 
        /* Event will be enabled by enabler sync. */
+       event_recorder->parent->run_filter = lttng_ust_interpret_event_filter;
        event_recorder->parent->enabled = 0;
        event_recorder->parent->priv->registered = 0;
-       CDS_INIT_LIST_HEAD(&event_recorder->parent->filter_bytecode_runtime_head);
+       CDS_INIT_LIST_HEAD(&event_recorder->parent->priv->filter_bytecode_runtime_head);
        CDS_INIT_LIST_HEAD(&event_recorder->parent->priv->enablers_ref_head);
        event_recorder->parent->priv->desc = desc;
 
@@ -847,11 +848,12 @@ int lttng_event_notifier_create(struct lttng_ust_event_desc *desc,
        event_notifier_priv->error_counter_index = error_counter_index;
 
        /* Event notifier will be enabled by enabler sync. */
+       event_notifier->parent->run_filter = lttng_ust_interpret_event_filter;
        event_notifier->parent->enabled = 0;
        event_notifier_priv->parent.registered = 0;
 
-       CDS_INIT_LIST_HEAD(&event_notifier->parent->filter_bytecode_runtime_head);
-       CDS_INIT_LIST_HEAD(&event_notifier->capture_bytecode_runtime_head);
+       CDS_INIT_LIST_HEAD(&event_notifier->parent->priv->filter_bytecode_runtime_head);
+       CDS_INIT_LIST_HEAD(&event_notifier->priv->capture_bytecode_runtime_head);
        CDS_INIT_LIST_HEAD(&event_notifier_priv->parent.enablers_ref_head);
        event_notifier_priv->parent.desc = desc;
        event_notifier->notification_send = lttng_event_notifier_notification_send;
@@ -1238,7 +1240,7 @@ int lttng_event_enabler_ref_event_recorders(struct lttng_event_enabler *event_en
                 */
                lttng_enabler_link_bytecode(event_recorder_priv->parent.desc,
                        &session->priv->ctx,
-                       &event_recorder_priv->pub->parent->filter_bytecode_runtime_head,
+                       &event_recorder_priv->parent.filter_bytecode_runtime_head,
                        &lttng_event_enabler_as_enabler(event_enabler)->filter_bytecode_head);
 
                /* TODO: merge event context. */
@@ -1654,7 +1656,8 @@ void lttng_session_sync_event_enablers(struct lttng_ust_session *session)
        cds_list_for_each_entry(event_recorder_priv, &session->priv->events_head, node) {
                struct lttng_enabler_ref *enabler_ref;
                struct lttng_ust_bytecode_runtime *runtime;
-               int enabled = 0, has_enablers_without_bytecode = 0;
+               int enabled = 0, has_enablers_without_filter_bytecode = 0;
+               int nr_filters = 0;
 
                /* Enable events */
                cds_list_for_each_entry(enabler_ref,
@@ -1689,18 +1692,21 @@ void lttng_session_sync_event_enablers(struct lttng_ust_session *session)
                                &event_recorder_priv->parent.enablers_ref_head, node) {
                        if (enabler_ref->ref->enabled
                                        && cds_list_empty(&enabler_ref->ref->filter_bytecode_head)) {
-                               has_enablers_without_bytecode = 1;
+                               has_enablers_without_filter_bytecode = 1;
                                break;
                        }
                }
-               event_recorder_priv->pub->parent->has_enablers_without_bytecode =
-                       has_enablers_without_bytecode;
+               event_recorder_priv->parent.has_enablers_without_filter_bytecode =
+                       has_enablers_without_filter_bytecode;
 
                /* Enable filters */
                cds_list_for_each_entry(runtime,
-                               &event_recorder_priv->pub->parent->filter_bytecode_runtime_head, node) {
+                               &event_recorder_priv->parent.filter_bytecode_runtime_head, node) {
                        lttng_bytecode_sync_state(runtime);
+                       nr_filters++;
                }
+               CMM_STORE_SHARED(event_recorder_priv->parent.pub->eval_filter,
+                       !(has_enablers_without_filter_bytecode || !nr_filters));
        }
        lttng_ust_tp_probe_prune_release_queue();
 }
@@ -1840,14 +1846,14 @@ int lttng_event_notifier_enabler_ref_event_notifiers(
                 */
                lttng_enabler_link_bytecode(event_notifier_priv->parent.desc,
                        &event_notifier_group->ctx,
-                       &event_notifier_priv->pub->parent->filter_bytecode_runtime_head,
+                       &event_notifier_priv->parent.filter_bytecode_runtime_head,
                        &lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)->filter_bytecode_head);
 
                /*
                 * Link capture bytecodes if not linked yet.
                 */
                lttng_enabler_link_bytecode(event_notifier_priv->parent.desc,
-                       &event_notifier_group->ctx, &event_notifier_priv->pub->capture_bytecode_runtime_head,
+                       &event_notifier_group->ctx, &event_notifier_priv->capture_bytecode_runtime_head,
                        &event_notifier_enabler->capture_bytecode_head);
 
                event_notifier_priv->num_captures = event_notifier_enabler->num_captures;
@@ -1872,7 +1878,8 @@ void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group
        cds_list_for_each_entry(event_notifier_priv, &event_notifier_group->event_notifiers_head, node) {
                struct lttng_enabler_ref *enabler_ref;
                struct lttng_ust_bytecode_runtime *runtime;
-               int enabled = 0, has_enablers_without_bytecode = 0;
+               int enabled = 0, has_enablers_without_filter_bytecode = 0;
+               int nr_filters = 0, nr_captures = 0;
 
                /* Enable event_notifiers */
                cds_list_for_each_entry(enabler_ref,
@@ -1901,24 +1908,30 @@ void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group
                                &event_notifier_priv->parent.enablers_ref_head, node) {
                        if (enabler_ref->ref->enabled
                                        && cds_list_empty(&enabler_ref->ref->filter_bytecode_head)) {
-                               has_enablers_without_bytecode = 1;
+                               has_enablers_without_filter_bytecode = 1;
                                break;
                        }
                }
-               event_notifier_priv->pub->parent->has_enablers_without_bytecode =
-                       has_enablers_without_bytecode;
+               event_notifier_priv->parent.has_enablers_without_filter_bytecode =
+                       has_enablers_without_filter_bytecode;
 
                /* Enable filters */
                cds_list_for_each_entry(runtime,
-                               &event_notifier_priv->pub->parent->filter_bytecode_runtime_head, node) {
+                               &event_notifier_priv->parent.filter_bytecode_runtime_head, node) {
                        lttng_bytecode_sync_state(runtime);
+                       nr_filters++;
                }
+               CMM_STORE_SHARED(event_notifier_priv->parent.pub->eval_filter,
+                       !(has_enablers_without_filter_bytecode || !nr_filters));
 
                /* Enable captures. */
                cds_list_for_each_entry(runtime,
-                               &event_notifier_priv->pub->capture_bytecode_runtime_head, node) {
+                               &event_notifier_priv->capture_bytecode_runtime_head, node) {
                        lttng_bytecode_sync_state(runtime);
+                       nr_captures++;
                }
+               CMM_STORE_SHARED(event_notifier_priv->pub->eval_capture,
+                               !!nr_captures);
        }
        lttng_ust_tp_probe_prune_release_queue();
 }
index 80b49f7f2dd50922e70b185555061751d27f4db7..54983cba3c6879a538c7a3053c450e62da895383 100644 (file)
@@ -31,6 +31,7 @@ struct lttng_ust_lib_ring_buffer_ctx;
 struct lttng_ust_ctx_value;
 struct lttng_ust_event_recorder;
 struct lttng_ust_event_notifier;
+struct lttng_ust_notification_ctx;
 
 __attribute__((visibility("hidden")))
 int ust_lock(void) __attribute__ ((warn_unused_result));
@@ -100,7 +101,8 @@ void lttng_ust_dummy_get_value(struct lttng_ust_ctx_field *field,
 __attribute__((visibility("hidden")))
 void lttng_event_notifier_notification_send(
                struct lttng_ust_event_notifier *event_notifier,
-               const char *stack_data);
+               const char *stack_data,
+               struct lttng_ust_notification_ctx *notif_ctx);
 
 __attribute__((visibility("hidden")))
 struct lttng_counter_transport *lttng_counter_transport_find(const char *name);
index 4e73e3e3e783c41222be8bd7d13fde16bebc623e..65023b3f8820de423d2c656fbd0393f2d242403a 100644 (file)
@@ -111,6 +111,26 @@ struct lttng_ust_bytecode_node {
        } bc;
 };
 
+/*
+ * Bytecode interpreter return value.
+ */
+enum lttng_ust_bytecode_interpreter_ret {
+       LTTNG_UST_BYTECODE_INTERPRETER_ERROR = -1,
+       LTTNG_UST_BYTECODE_INTERPRETER_OK = 0,
+};
+
+struct lttng_interpreter_output;
+struct lttng_ust_bytecode_runtime_private;
+
+enum lttng_ust_bytecode_filter_result {
+       LTTNG_UST_BYTECODE_FILTER_ACCEPT = 0,
+       LTTNG_UST_BYTECODE_FILTER_REJECT = 1,
+};
+
+struct lttng_ust_bytecode_filter_ctx {
+       enum lttng_ust_bytecode_filter_result result;
+};
+
 struct lttng_ust_excluder_node {
        struct cds_list_head node;
        struct lttng_enabler *enabler;
@@ -250,6 +270,10 @@ struct lttng_ust_event_common_private {
        struct cds_list_head enablers_ref_head;
        int registered;                 /* has reg'd tracepoint probe */
        uint64_t user_token;
+
+       int has_enablers_without_filter_bytecode;
+       /* list of struct lttng_ust_bytecode_runtime, sorted by seqnum */
+       struct cds_list_head filter_bytecode_runtime_head;
 };
 
 struct lttng_ust_event_recorder_private {
@@ -270,14 +294,18 @@ struct lttng_ust_event_notifier_private {
        uint64_t error_counter_index;
        struct cds_list_head node;              /* Event notifier list */
        struct cds_hlist_node hlist;            /* Hash table of event notifiers */
-};
+       struct cds_list_head capture_bytecode_runtime_head;
 
-struct lttng_ust_bytecode_runtime_private {
-       struct bytecode_runtime *pub;   /* Public bytecode runtime interface */
+};
 
+struct lttng_ust_bytecode_runtime {
        enum lttng_ust_bytecode_type type;
        struct lttng_ust_bytecode_node *bc;
        int link_failed;
+       int (*interpreter_func)(struct lttng_ust_bytecode_runtime *bytecode_runtime,
+                       const char *interpreter_stack_data,
+                       void *ctx);
+       struct cds_list_head node;      /* list of bytecode runtime in event */
        /*
         * Pointer to a URCU-protected pointer owned by an `struct
         * lttng_session`or `struct lttng_event_notifier_group`.
@@ -864,4 +892,9 @@ struct lttng_ust_channel_buffer *lttng_ust_alloc_channel_buffer(void);
 __attribute__((visibility("hidden")))
 void lttng_ust_free_channel_common(struct lttng_ust_channel_common *chan);
 
+__attribute__((visibility("hidden")))
+int lttng_ust_interpret_event_filter(struct lttng_ust_event_common *event,
+               const char *interpreter_stack_data,
+               void *filter_ctx);
+
 #endif /* _LTTNG_UST_EVENTS_INTERNAL_H */
This page took 0.039129 seconds and 4 git commands to generate.