Refactor notification error counters
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 10 Feb 2022 17:52:54 +0000 (12:52 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Jul 2024 20:58:48 +0000 (16:58 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I106b6fe85f899297582e131252c591ac5ba7d538

include/lttng/events-internal.h
include/lttng/events.h
src/lttng-abi.c
src/lttng-counter-client-percpu-32-modular.c
src/lttng-counter-client-percpu-64-modular.c
src/lttng-event-notifier-notification.c
src/lttng-events.c

index 80d81f3a806d54c0c4f30997497b41eb729e3bea..9a28b197cecf22b12d868fd9a0a91c25eb35291a 100644 (file)
@@ -233,9 +233,17 @@ struct lttng_kernel_channel_counter_ops_private {
        void (*counter_destroy)(struct lttng_kernel_channel_counter *counter);
        int (*counter_add)(struct lttng_kernel_channel_counter *counter,
                        const size_t *dimension_indexes, int64_t v);
+       /*
+        * counter_read reads a specific cpu's counter if @cpu >= 0, or
+        * the global aggregation counter if @cpu == -1.
+        */
        int (*counter_read)(struct lttng_kernel_channel_counter *counter,
                        const size_t *dimension_indexes, int cpu,
                        int64_t *value, bool *overflow, bool *underflow);
+       /*
+        * counter_aggregate returns the total sum of all per-cpu counters and
+        * the global aggregation counter.
+        */
        int (*counter_aggregate)(struct lttng_kernel_channel_counter *counter,
                        const size_t *dimension_indexes, int64_t *value,
                        bool *overflow, bool *underflow);
@@ -250,6 +258,11 @@ struct lttng_kernel_channel_counter_private {
        struct lib_counter *counter;
        struct lttng_kernel_channel_counter_ops *ops;
 
+       /* Owned either by session or event notifier group. */
+
+       /* Session or event notifier group file owner. */
+       struct file *owner;
+
        /* Event notifier group owner. */
        struct lttng_event_notifier_group *event_notifier_group;
 
@@ -257,6 +270,7 @@ struct lttng_kernel_channel_counter_private {
        struct lttng_session *session;
        struct list_head node;                          /* Counter list (in session) */
        size_t free_index;                              /* Next index to allocate */
+       struct lttng_counter_transport *transport;
 };
 
 enum lttng_kernel_bytecode_interpreter_ret {
@@ -474,34 +488,17 @@ struct lttng_kernel_channel_buffer_ops_private {
                        uint64_t *id);
 };
 
-struct lttng_counter_ops {
-       struct lib_counter *(*counter_create)(size_t nr_dimensions,
-                       const size_t *max_nr_elem,      /* for each dimension */
-                       int64_t global_sum_step);
-       void (*counter_destroy)(struct lib_counter *counter);
-       int (*counter_add)(struct lib_counter *counter, const size_t *dimension_indexes,
-                       int64_t v);
-       /*
-        * counter_read reads a specific cpu's counter if @cpu >= 0, or
-        * the global aggregation counter if @cpu == -1.
-        */
-       int (*counter_read)(struct lib_counter *counter, const size_t *dimension_indexes, int cpu,
-                        int64_t *value, bool *overflow, bool *underflow);
-       /*
-        * counter_aggregate returns the total sum of all per-cpu counters and
-        * the global aggregation counter.
-        */
-       int (*counter_aggregate)(struct lib_counter *counter, const size_t *dimension_indexes,
-                       int64_t *value, bool *overflow, bool *underflow);
-       int (*counter_clear)(struct lib_counter *counter, const size_t *dimension_indexes);
+struct lttng_counter_map_descriptor {
+       uint64_t user_token;
+       size_t array_index;
+       char key[LTTNG_KERNEL_ABI_COUNTER_KEY_LEN];
 };
 
-struct lttng_counter {
-       struct file *file;              /* File associated to counter. */
-       struct file *owner;
-       struct lttng_counter_transport *transport;
-       struct lib_counter *counter;
-       struct lttng_counter_ops *ops;
+struct lttng_counter_map {
+       struct lttng_counter_map_descriptor *descriptors;
+       size_t nr_descriptors;
+       size_t alloc_len;
+       struct mutex lock;              /* counter map lock */
 };
 
 #define LTTNG_EVENT_HT_BITS            12
@@ -527,7 +524,7 @@ struct lttng_event_notifier_group {
 
        struct lttng_kernel_syscall_table syscall_table;
 
-       struct lttng_counter *error_counter;
+       struct lttng_kernel_channel_counter *error_counter;
        size_t error_counter_len;
 };
 
@@ -542,7 +539,7 @@ struct lttng_counter_transport {
        char *name;
        struct module *owner;
        struct list_head node;
-       struct lttng_counter_ops ops;
+       struct lttng_kernel_channel_counter_ops ops;
 };
 
 struct lttng_kernel_session_private {
@@ -1124,16 +1121,19 @@ int lttng_session_metadata_regenerate(struct lttng_kernel_session *session);
 int lttng_session_statedump(struct lttng_kernel_session *session);
 void metadata_cache_destroy(struct kref *kref);
 
-struct lttng_counter *lttng_kernel_counter_create(
-               const char *counter_transport_name, size_t number_dimensions,
-               const size_t *dimensions_sizes);
-int lttng_kernel_counter_read(struct lttng_counter *counter,
+struct lttng_kernel_channel_counter *lttng_kernel_counter_create(
+               const char *counter_transport_name,
+               size_t number_dimensions,
+               const struct lttng_counter_dimension *dimensions,
+               int64_t global_sum_step,
+               bool coalesce_hits);
+int lttng_kernel_counter_read(struct lttng_kernel_channel_counter *counter,
                const size_t *dimension_indexes, int32_t cpu,
                int64_t *val, bool *overflow, bool *underflow);
-int lttng_kernel_counter_aggregate(struct lttng_counter *counter,
+int lttng_kernel_counter_aggregate(struct lttng_kernel_channel_counter *counter,
                const size_t *dimension_indexes, int64_t *val,
                bool *overflow, bool *underflow);
-int lttng_kernel_counter_clear(struct lttng_counter *counter,
+int lttng_kernel_counter_clear(struct lttng_kernel_channel_counter *counter,
                const size_t *dimension_indexes);
 struct lttng_event_notifier_group *lttng_event_notifier_group_create(void);
 int lttng_event_notifier_group_create_error_counter(
@@ -1221,6 +1221,10 @@ int lttng_calibrate(struct lttng_kernel_abi_calibrate *calibrate);
 extern const struct file_operations lttng_tracepoint_list_fops;
 extern const struct file_operations lttng_syscall_list_fops;
 
+struct lttng_kernel_channel_buffer *lttng_kernel_alloc_channel_buffer(void);
+struct lttng_kernel_channel_counter *lttng_kernel_alloc_channel_counter(void);
+void lttng_kernel_free_channel_common(struct lttng_kernel_channel_common *chan);
+
 #define lttng_kernel_static_ctx_field(_event_field, _get_size, _record, _get_value, _destroy, _priv)   \
        __LTTNG_COMPOUND_LITERAL(const struct lttng_kernel_ctx_field, {                                 \
                .event_field = (_event_field),                                                          \
index e6bfb412928bde88084fae040109b96f0064120a..ba30c2b7108d27584901c0ead4e4e751d4454c79 100644 (file)
@@ -426,6 +426,7 @@ struct lttng_kernel_channel_buffer_ops {
 
 enum lttng_kernel_channel_type {
        LTTNG_KERNEL_CHANNEL_TYPE_BUFFER = 0,
+       LTTNG_KERNEL_CHANNEL_TYPE_COUNTER = 1,
 };
 
 struct lttng_kernel_channel_common_private;
index 36dbddde4eb53424b42a0d20fdc8db18dd977fe9..93df4a638d789c7fc0b0553a7e9a08b8ac10cc45 100644 (file)
@@ -613,14 +613,14 @@ int lttng_abi_session_set_creation_time(struct lttng_kernel_session *session,
 static
 int lttng_counter_release(struct inode *inode, struct file *file)
 {
-       struct lttng_counter *counter = file->private_data;
+       struct lttng_kernel_channel_counter *counter = file->private_data;
 
        if (counter) {
                /*
                 * Do not destroy the counter itself. Wait of the owner
                 * (event_notifier group) to be destroyed.
                 */
-               fput(counter->owner);
+               fput(counter->priv->owner);
        }
 
        return 0;
@@ -629,7 +629,7 @@ int lttng_counter_release(struct inode *inode, struct file *file)
 static
 long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       struct lttng_counter *counter = file->private_data;
+       struct lttng_kernel_channel_counter *counter = file->private_data;
        size_t indexes[LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX] = { 0 };
        int i;
 
@@ -652,14 +652,12 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        return -EINVAL;
                if (local_counter_read.index.number_dimensions > LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX)
                        return -EINVAL;
-
                /* Cast all indexes into size_t. */
                for (i = 0; i < local_counter_read.index.number_dimensions; i++)
-                       indexes[i] = (size_t) local_counter_read.index.dimension_indexes[i];
+                       indexes[i] = local_counter_read.index.dimension_indexes[i];
                cpu = local_counter_read.cpu;
 
-               ret = lttng_kernel_counter_read(counter, indexes, cpu, &value,
-                               &overflow, &underflow);
+               ret = lttng_kernel_counter_read(counter, indexes, cpu, &value, &overflow, &underflow);
                if (ret)
                        return ret;
                local_counter_read.value.value = value;
@@ -689,13 +687,11 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        return -EINVAL;
                if (local_counter_aggregate.index.number_dimensions > LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX)
                        return -EINVAL;
-
                /* Cast all indexes into size_t. */
                for (i = 0; i < local_counter_aggregate.index.number_dimensions; i++)
-                       indexes[i] = (size_t) local_counter_aggregate.index.dimension_indexes[i];
+                       indexes[i] = local_counter_aggregate.index.dimension_indexes[i];
 
-               ret = lttng_kernel_counter_aggregate(counter, indexes, &value,
-                               &overflow, &underflow);
+               ret = lttng_kernel_counter_aggregate(counter, indexes, &value, &overflow, &underflow);
                if (ret)
                        return ret;
                local_counter_aggregate.value.value = value;
@@ -722,11 +718,9 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        return -EINVAL;
                if (local_counter_clear.index.number_dimensions > LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX)
                        return -EINVAL;
-
                /* Cast all indexes into size_t. */
                for (i = 0; i < local_counter_clear.index.number_dimensions; i++)
-                       indexes[i] = (size_t) local_counter_clear.index.dimension_indexes[i];
-
+                       indexes[i] = local_counter_clear.index.dimension_indexes[i];
                return lttng_kernel_counter_clear(counter, indexes);
        }
        default:
@@ -2209,11 +2203,12 @@ long lttng_abi_event_notifier_group_create_error_counter(
 {
        int counter_fd, ret;
        char *counter_transport_name;
-       size_t counter_len;
-       struct lttng_counter *counter = NULL;
+       struct lttng_kernel_channel_counter *chan_counter = NULL;
        struct file *counter_file;
        struct lttng_event_notifier_group *event_notifier_group =
                        (struct lttng_event_notifier_group *) event_notifier_group_file->private_data;
+       struct lttng_counter_dimension dimensions[1];
+       size_t counter_len;
 
        if (error_counter_conf->arithmetic != LTTNG_KERNEL_ABI_COUNTER_ARITHMETIC_MODULAR) {
                printk(KERN_ERR "LTTng: event_notifier: Error counter of the wrong arithmetic type.\n");
@@ -2264,39 +2259,41 @@ long lttng_abi_event_notifier_group_create_error_counter(
        }
 
        counter_len = error_counter_conf->dimensions[0].size;
+       dimensions[0].size = counter_len;
+       dimensions[0].underflow_index = 0;
+       dimensions[0].overflow_index = 0;
+       dimensions[0].has_underflow = 0;
+       dimensions[0].has_overflow = 0;
 
        if (!atomic_long_add_unless(&event_notifier_group_file->f_count, 1, LONG_MAX)) {
                ret = -EOVERFLOW;
                goto refcount_error;
        }
 
-       counter = lttng_kernel_counter_create(counter_transport_name,
-                       1, &counter_len);
-       if (!counter) {
+       chan_counter = lttng_kernel_counter_create(counter_transport_name, 1, dimensions, 0, false);
+       if (!chan_counter) {
                ret = -EINVAL;
-               goto counter_error;
+               goto create_error;
        }
 
+       chan_counter->priv->parent.file = counter_file;
+       chan_counter->priv->owner = event_notifier_group->file;
+       counter_file->private_data = chan_counter;
        event_notifier_group->error_counter_len = counter_len;
        /*
         * store-release to publish error counter matches load-acquire
         * in record_error. Ensures the counter is created and the
         * error_counter_len is set before they are used.
         */
-       smp_store_release(&event_notifier_group->error_counter, counter);
-
-       counter->file = counter_file;
-       counter->owner = event_notifier_group->file;
-       counter_file->private_data = counter;
-       /* Ownership transferred. */
-       counter = NULL;
+       smp_store_release(&event_notifier_group->error_counter,
+                               chan_counter);
 
        fd_install(counter_fd, counter_file);
        lttng_unlock_sessions();
 
        return counter_fd;
 
-counter_error:
+create_error:
        atomic_long_dec(&event_notifier_group_file->f_count);
 refcount_error:
        fput(counter_file);
index 35a8b54fa2b8d7cabd4e7306954811b55d1a4d51..421b04ae4d28db329edcf0a30c936f8faf581ec8 100644 (file)
@@ -22,53 +22,89 @@ static const struct lib_counter_config client_config = {
        .counter_size = COUNTER_SIZE_32_BIT,
 };
 
-static struct lib_counter *counter_create(size_t nr_dimensions,
-                                         const size_t *max_nr_elem,
+static struct lttng_kernel_channel_counter *counter_create(size_t nr_dimensions,
+                                         const struct lttng_counter_dimension *dimensions,
                                          int64_t global_sum_step)
 {
-       return lttng_counter_create(&client_config, nr_dimensions, max_nr_elem,
+       size_t max_nr_elem[LTTNG_COUNTER_DIMENSION_MAX], i;
+       struct lttng_kernel_channel_counter *lttng_chan_counter;
+       struct lib_counter *counter;
+
+       if (nr_dimensions > LTTNG_COUNTER_DIMENSION_MAX)
+               return NULL;
+       for (i = 0; i < nr_dimensions; i++) {
+               if (dimensions[i].has_underflow || dimensions[i].has_overflow)
+                       return NULL;
+               max_nr_elem[i] = dimensions[i].size;
+       }
+       lttng_chan_counter = lttng_kernel_alloc_channel_counter();
+       if (!lttng_chan_counter)
+               return NULL;
+       counter = lttng_counter_create(&client_config, nr_dimensions, max_nr_elem,
                                    global_sum_step);
+       if (!counter)
+               goto error;
+       lttng_chan_counter->priv->counter = counter;
+       return lttng_chan_counter;
+
+error:
+       lttng_kernel_free_channel_common(&lttng_chan_counter->parent);
+       return NULL;
+}
+
+static void counter_destroy(struct lttng_kernel_channel_counter *counter)
+{
+       lttng_counter_destroy(counter->priv->counter);
+       lttng_kernel_free_channel_common(&counter->parent);
 }
 
-static void counter_destroy(struct lib_counter *counter)
+static int counter_add(struct lttng_kernel_channel_counter *counter,
+                      const size_t *dimension_indexes, int64_t v)
 {
-       return lttng_counter_destroy(counter);
+       return lttng_counter_add(&client_config, counter->priv->counter, dimension_indexes, v);
 }
 
-static int counter_add(struct lib_counter *counter, const size_t *dimension_indexes, int64_t v)
+static int event_counter_add(struct lttng_kernel_event_counter *event_counter, int64_t v)
 {
-       return lttng_counter_add(&client_config, counter, dimension_indexes, v);
+       struct lttng_kernel_channel_counter *counter = event_counter->chan;
+       size_t index = event_counter->priv->parent.id;
+
+       return counter_add(counter, &index, v);
 }
 
-static int counter_read(struct lib_counter *counter, const size_t *dimension_indexes, int cpu,
+static int counter_read(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes, int cpu,
                        int64_t *value, bool *overflow, bool *underflow)
 {
-       return lttng_counter_read(&client_config, counter, dimension_indexes, cpu, value,
+       return lttng_counter_read(&client_config, counter->priv->counter, dimension_indexes, cpu, value,
                                  overflow, underflow);
 }
 
-static int counter_aggregate(struct lib_counter *counter, const size_t *dimension_indexes,
+static int counter_aggregate(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes,
                             int64_t *value, bool *overflow, bool *underflow)
 {
-       return lttng_counter_aggregate(&client_config, counter, dimension_indexes, value,
+       return lttng_counter_aggregate(&client_config, counter->priv->counter, dimension_indexes, value,
                                       overflow, underflow);
 }
 
-static int counter_clear(struct lib_counter *counter, const size_t *dimension_indexes)
+static int counter_clear(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes)
 {
-       return lttng_counter_clear(&client_config, counter, dimension_indexes);
+       return lttng_counter_clear(&client_config, counter->priv->counter, dimension_indexes);
 }
 
 static struct lttng_counter_transport lttng_counter_transport = {
        .name = "counter-per-cpu-32-modular",
        .owner = THIS_MODULE,
        .ops = {
-               .counter_create = counter_create,
-               .counter_destroy = counter_destroy,
-               .counter_add = counter_add,
-               .counter_read = counter_read,
-               .counter_aggregate = counter_aggregate,
-               .counter_clear = counter_clear,
+               .priv = __LTTNG_COMPOUND_LITERAL(struct lttng_kernel_channel_counter_ops_private, {
+                       .pub = &lttng_counter_transport.ops,
+                       .counter_create = counter_create,
+                       .counter_destroy = counter_destroy,
+                       .counter_add = counter_add,
+                       .counter_read = counter_read,
+                       .counter_aggregate = counter_aggregate,
+                       .counter_clear = counter_clear,
+               }),
+               .event_counter_add = event_counter_add,
        },
 };
 
index 771bed3e214ea8abdb97e49319fc5e0805dbc1a8..6050ebc9045a788e4d23e7b9a58f9b111d2a475e 100644 (file)
@@ -22,53 +22,89 @@ static const struct lib_counter_config client_config = {
        .counter_size = COUNTER_SIZE_64_BIT,
 };
 
-static struct lib_counter *counter_create(size_t nr_dimensions,
-                                         const size_t *max_nr_elem,
+static struct lttng_kernel_channel_counter *counter_create(size_t nr_dimensions,
+                                         const struct lttng_counter_dimension *dimensions,
                                          int64_t global_sum_step)
 {
-       return lttng_counter_create(&client_config, nr_dimensions, max_nr_elem,
+       size_t max_nr_elem[LTTNG_COUNTER_DIMENSION_MAX], i;
+       struct lttng_kernel_channel_counter *lttng_chan_counter;
+       struct lib_counter *counter;
+
+       if (nr_dimensions > LTTNG_COUNTER_DIMENSION_MAX)
+               return NULL;
+       for (i = 0; i < nr_dimensions; i++) {
+               if (dimensions[i].has_underflow || dimensions[i].has_overflow)
+                       return NULL;
+               max_nr_elem[i] = dimensions[i].size;
+       }
+       lttng_chan_counter = lttng_kernel_alloc_channel_counter();
+       if (!lttng_chan_counter)
+               return NULL;
+       counter = lttng_counter_create(&client_config, nr_dimensions, max_nr_elem,
                                    global_sum_step);
+       if (!counter)
+               goto error;
+       lttng_chan_counter->priv->counter = counter;
+       return lttng_chan_counter;
+
+error:
+       lttng_kernel_free_channel_common(&lttng_chan_counter->parent);
+       return NULL;
+}
+
+static void counter_destroy(struct lttng_kernel_channel_counter *counter)
+{
+       lttng_counter_destroy(counter->priv->counter);
+       lttng_kernel_free_channel_common(&counter->parent);
 }
 
-static void counter_destroy(struct lib_counter *counter)
+static int counter_add(struct lttng_kernel_channel_counter *counter,
+                      const size_t *dimension_indexes, int64_t v)
 {
-       return lttng_counter_destroy(counter);
+       return lttng_counter_add(&client_config, counter->priv->counter, dimension_indexes, v);
 }
 
-static int counter_add(struct lib_counter *counter, const size_t *dimension_indexes, int64_t v)
+static int event_counter_add(struct lttng_kernel_event_counter *event_counter, int64_t v)
 {
-       return lttng_counter_add(&client_config, counter, dimension_indexes, v);
+       struct lttng_kernel_channel_counter *counter = event_counter->chan;
+       size_t index = event_counter->priv->parent.id;
+
+       return counter_add(counter, &index, v);
 }
 
-static int counter_read(struct lib_counter *counter, const size_t *dimension_indexes, int cpu,
+static int counter_read(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes, int cpu,
                        int64_t *value, bool *overflow, bool *underflow)
 {
-       return lttng_counter_read(&client_config, counter, dimension_indexes, cpu, value,
+       return lttng_counter_read(&client_config, counter->priv->counter, dimension_indexes, cpu, value,
                                  overflow, underflow);
 }
 
-static int counter_aggregate(struct lib_counter *counter, const size_t *dimension_indexes,
+static int counter_aggregate(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes,
                             int64_t *value, bool *overflow, bool *underflow)
 {
-       return lttng_counter_aggregate(&client_config, counter, dimension_indexes, value,
+       return lttng_counter_aggregate(&client_config, counter->priv->counter, dimension_indexes, value,
                                       overflow, underflow);
 }
 
-static int counter_clear(struct lib_counter *counter, const size_t *dimension_indexes)
+static int counter_clear(struct lttng_kernel_channel_counter *counter, const size_t *dimension_indexes)
 {
-       return lttng_counter_clear(&client_config, counter, dimension_indexes);
+       return lttng_counter_clear(&client_config, counter->priv->counter, dimension_indexes);
 }
 
 static struct lttng_counter_transport lttng_counter_transport = {
        .name = "counter-per-cpu-64-modular",
        .owner = THIS_MODULE,
        .ops = {
-               .counter_create = counter_create,
-               .counter_destroy = counter_destroy,
-               .counter_add = counter_add,
-               .counter_read = counter_read,
-               .counter_aggregate = counter_aggregate,
-               .counter_clear = counter_clear,
+               .priv = __LTTNG_COMPOUND_LITERAL(struct lttng_kernel_channel_counter_ops_private, {
+                       .pub = &lttng_counter_transport.ops,
+                       .counter_create = counter_create,
+                       .counter_destroy = counter_destroy,
+                       .counter_add = counter_add,
+                       .counter_read = counter_read,
+                       .counter_aggregate = counter_aggregate,
+                       .counter_clear = counter_clear,
+               }),
+               .event_counter_add = event_counter_add,
        },
 };
 
index 29d2d1567b80242182fd2a68cffff05da8cb5f59..290e57e31c1c25ace97b9cbde3407b560bea248f 100644 (file)
@@ -394,7 +394,7 @@ void record_error(struct lttng_kernel_event_notifier *event_notifier)
 {
 
        struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
-       struct lttng_counter *error_counter;
+       struct lttng_kernel_channel_counter *error_counter;
        size_t dimension_index[1];
        int ret;
 
@@ -410,8 +410,7 @@ void record_error(struct lttng_kernel_event_notifier *event_notifier)
 
        dimension_index[0] = event_notifier->priv->error_counter_index;
 
-       ret = error_counter->ops->counter_add(error_counter->counter,
-                       dimension_index, 1);
+       ret = error_counter->ops->priv->counter_add(error_counter, dimension_index, 1);
        if (ret)
                WARN_ON_ONCE(1);
 }
index 3f15965c3ba60e07cf20570ed81dbd50b2c45ce8..2458b279cca0dd992921999a0acaa6d89d75e89f 100644 (file)
@@ -232,12 +232,15 @@ struct lttng_counter_transport *lttng_counter_transport_find(const char *name)
        return NULL;
 }
 
-struct lttng_counter *lttng_kernel_counter_create(
+struct lttng_kernel_channel_counter *lttng_kernel_counter_create(
                const char *counter_transport_name,
-               size_t number_dimensions, const size_t *dimensions_sizes)
+               size_t number_dimensions,
+               const struct lttng_counter_dimension *dimensions,
+               int64_t global_sum_step,
+               bool coalesce_hits)
 {
-       struct lttng_counter *counter = NULL;
        struct lttng_counter_transport *counter_transport = NULL;
+       struct lttng_kernel_channel_counter *counter = NULL;
 
        counter_transport = lttng_counter_transport_find(counter_transport_name);
        if (!counter_transport) {
@@ -250,31 +253,34 @@ struct lttng_counter *lttng_kernel_counter_create(
                goto notransport;
        }
 
-       counter = lttng_kvzalloc(sizeof(struct lttng_counter), GFP_KERNEL);
+       counter = counter_transport->ops.priv->counter_create(number_dimensions, dimensions,
+                       global_sum_step);
        if (!counter)
-               goto nomem;
+               goto create_error;
 
        /* Create event notifier error counter. */
        counter->ops = &counter_transport->ops;
-       counter->transport = counter_transport;
-
-       counter->counter = counter->ops->counter_create(
-                       number_dimensions, dimensions_sizes, 0);
-       if (!counter->counter) {
-               goto create_error;
-       }
+       counter->priv->parent.coalesce_hits = coalesce_hits;
+       counter->priv->transport = counter_transport;
 
        return counter;
 
 create_error:
-       lttng_kvfree(counter);
-nomem:
        if (counter_transport)
                module_put(counter_transport->owner);
 notransport:
        return NULL;
 }
 
+static
+void lttng_kernel_counter_destroy(struct lttng_kernel_channel_counter *counter)
+{
+       struct lttng_counter_transport *counter_transport = counter->priv->transport;
+
+       counter->ops->priv->counter_destroy(counter);
+       module_put(counter_transport->owner);
+}
+
 struct lttng_event_notifier_group *lttng_event_notifier_group_create(void)
 {
        struct lttng_transport *transport = NULL;
@@ -429,14 +435,8 @@ void lttng_event_notifier_group_destroy(
                        &event_notifier_group->event_notifiers_head, parent.node)
                _lttng_event_destroy(&event_notifier_priv->pub->parent);
 
-       if (event_notifier_group->error_counter) {
-               struct lttng_counter *error_counter = event_notifier_group->error_counter;
-
-               error_counter->ops->counter_destroy(error_counter->counter);
-               module_put(error_counter->transport->owner);
-               lttng_kvfree(error_counter);
-               event_notifier_group->error_counter = NULL;
-       }
+       if (event_notifier_group->error_counter)
+               lttng_kernel_counter_destroy(event_notifier_group->error_counter);
 
        event_notifier_group->ops->priv->channel_destroy(event_notifier_group->chan);
        module_put(event_notifier_group->transport->owner);
@@ -769,7 +769,6 @@ struct lttng_kernel_channel_buffer *lttng_channel_buffer_create(struct lttng_ker
                                       enum channel_type channel_type)
 {
        struct lttng_kernel_channel_buffer *chan;
-       struct lttng_kernel_channel_buffer_private *chan_priv;
        struct lttng_transport *transport = NULL;
 
        mutex_lock(&sessions_mutex);
@@ -785,15 +784,9 @@ struct lttng_kernel_channel_buffer *lttng_channel_buffer_create(struct lttng_ker
                printk(KERN_WARNING "LTTng: Can't lock transport module.\n");
                goto notransport;
        }
-       chan = kzalloc(sizeof(struct lttng_kernel_channel_buffer), GFP_KERNEL);
+       chan = lttng_kernel_alloc_channel_buffer();
        if (!chan)
                goto nomem;
-       chan_priv = kzalloc(sizeof(struct lttng_kernel_channel_buffer_private), GFP_KERNEL);
-       if (!chan_priv)
-               goto nomem_priv;
-       chan->priv = chan_priv;
-       chan_priv->pub = chan;
-       chan->parent.type = LTTNG_KERNEL_CHANNEL_TYPE_BUFFER;
        chan->parent.session = session;
        chan->priv->id = session->priv->free_chan_id++;
        chan->ops = &transport->ops;
@@ -816,9 +809,7 @@ struct lttng_kernel_channel_buffer *lttng_channel_buffer_create(struct lttng_ker
        return chan;
 
 create_error:
-       kfree(chan_priv);
-nomem_priv:
-       kfree(chan);
+       lttng_kernel_free_channel_common(&chan->parent);
 nomem:
        if (transport)
                module_put(transport->owner);
@@ -1060,12 +1051,15 @@ int lttng_kernel_event_notifier_clear_error_counter(struct lttng_kernel_event_co
 {
        switch (event->type) {
        case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
+               lttng_fallthrough;
+       case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
                return 0;
+
        case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
        {
                struct lttng_kernel_event_notifier *event_notifier =
                        container_of(event, struct lttng_kernel_event_notifier, parent);
-               struct lttng_counter *error_counter;
+               struct lttng_kernel_channel_counter *error_counter;
                struct lttng_event_notifier_group *event_notifier_group = event_notifier->priv->group;
                size_t dimension_index[1];
                int ret;
@@ -1089,7 +1083,7 @@ int lttng_kernel_event_notifier_clear_error_counter(struct lttng_kernel_event_co
                }
 
                dimension_index[0] = event_notifier->priv->error_counter_index;
-               ret = error_counter->ops->counter_clear(error_counter->counter, dimension_index);
+               ret = error_counter->ops->priv->counter_clear(error_counter, dimension_index);
                if (ret) {
                        printk(KERN_INFO "LTTng: event_notifier: Unable to clear error counter bucket %llu\n",
                                event_notifier->priv->error_counter_index);
@@ -1356,26 +1350,26 @@ struct lttng_kernel_event_common *lttng_kernel_event_create(struct lttng_event_e
        return event;
 }
 
-int lttng_kernel_counter_read(struct lttng_counter *counter,
+int lttng_kernel_counter_read(struct lttng_kernel_channel_counter *counter,
                const size_t *dim_indexes, int32_t cpu,
                int64_t *val, bool *overflow, bool *underflow)
 {
-       return counter->ops->counter_read(counter->counter, dim_indexes,
+       return counter->ops->priv->counter_read(counter, dim_indexes,
                        cpu, val, overflow, underflow);
 }
 
-int lttng_kernel_counter_aggregate(struct lttng_counter *counter,
+int lttng_kernel_counter_aggregate(struct lttng_kernel_channel_counter *counter,
                const size_t *dim_indexes, int64_t *val,
                bool *overflow, bool *underflow)
 {
-       return counter->ops->counter_aggregate(counter->counter, dim_indexes,
+       return counter->ops->priv->counter_aggregate(counter, dim_indexes,
                        val, overflow, underflow);
 }
 
-int lttng_kernel_counter_clear(struct lttng_counter *counter,
+int lttng_kernel_counter_clear(struct lttng_kernel_channel_counter *counter,
                const size_t *dim_indexes)
 {
-       return counter->ops->counter_clear(counter->counter, dim_indexes);
+       return counter->ops->priv->counter_clear(counter, dim_indexes);
 }
 
 /* Only used for tracepoints and system calls for now. */
@@ -4053,6 +4047,87 @@ void lttng_counter_transport_unregister(struct lttng_counter_transport *transpor
 }
 EXPORT_SYMBOL_GPL(lttng_counter_transport_unregister);
 
+struct lttng_kernel_channel_buffer *lttng_kernel_alloc_channel_buffer(void)
+{
+       struct lttng_kernel_channel_buffer *lttng_chan_buf;
+       struct lttng_kernel_channel_common *lttng_chan_common;
+       struct lttng_kernel_channel_buffer_private *lttng_chan_buf_priv;
+
+       lttng_chan_buf = kzalloc(sizeof(struct lttng_kernel_channel_buffer), GFP_KERNEL);
+       if (!lttng_chan_buf)
+               goto nomem;
+       lttng_chan_buf_priv = kzalloc(sizeof(struct lttng_kernel_channel_buffer_private), GFP_KERNEL);
+       if (!lttng_chan_buf_priv)
+               goto nomem_priv;
+       lttng_chan_common = &lttng_chan_buf->parent;
+       lttng_chan_common->type = LTTNG_KERNEL_CHANNEL_TYPE_BUFFER;
+       lttng_chan_buf->priv = lttng_chan_buf_priv;
+       lttng_chan_common->priv = &lttng_chan_buf_priv->parent;
+       lttng_chan_buf_priv->pub = lttng_chan_buf;
+       lttng_chan_buf_priv->parent.pub = lttng_chan_common;
+       return lttng_chan_buf;
+
+nomem_priv:
+       kfree(lttng_chan_buf);
+nomem:
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(lttng_kernel_alloc_channel_buffer);
+
+struct lttng_kernel_channel_counter *lttng_kernel_alloc_channel_counter(void)
+{
+       struct lttng_kernel_channel_counter *lttng_chan_counter;
+       struct lttng_kernel_channel_common *lttng_chan_common;
+       struct lttng_kernel_channel_counter_private *lttng_chan_counter_priv;
+
+       lttng_chan_counter = kzalloc(sizeof(struct lttng_kernel_channel_counter), GFP_KERNEL);
+       if (!lttng_chan_counter)
+               goto nomem;
+       lttng_chan_counter_priv = kzalloc(sizeof(struct lttng_kernel_channel_counter_private), GFP_KERNEL);
+       if (!lttng_chan_counter_priv)
+               goto nomem_priv;
+       lttng_chan_common = &lttng_chan_counter->parent;
+       lttng_chan_common->type = LTTNG_KERNEL_CHANNEL_TYPE_COUNTER;
+       lttng_chan_counter->priv = lttng_chan_counter_priv;
+       lttng_chan_common->priv = &lttng_chan_counter_priv->parent;
+       lttng_chan_counter_priv->pub = lttng_chan_counter;
+       lttng_chan_counter_priv->parent.pub = lttng_chan_common;
+       return lttng_chan_counter;
+
+nomem_priv:
+       kfree(lttng_chan_counter);
+nomem:
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(lttng_kernel_alloc_channel_counter);
+
+void lttng_kernel_free_channel_common(struct lttng_kernel_channel_common *chan)
+{
+       switch (chan->type) {
+       case LTTNG_KERNEL_CHANNEL_TYPE_BUFFER:
+       {
+               struct lttng_kernel_channel_buffer *chan_buf = container_of(chan,
+                               struct lttng_kernel_channel_buffer, parent);
+
+               kfree(chan_buf->priv);
+               kfree(chan_buf);
+               break;
+       }
+       case LTTNG_KERNEL_CHANNEL_TYPE_COUNTER:
+       {
+               struct lttng_kernel_channel_counter *chan_counter = container_of(chan,
+                               struct lttng_kernel_channel_counter, parent);
+
+               kfree(chan_counter->priv);
+               kfree(chan_counter);
+               break;
+       }
+       default:
+               WARN_ON_ONCE(1);
+       }
+}
+EXPORT_SYMBOL_GPL(lttng_kernel_free_channel_common);
+
 #if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(4,10,0))
 
 enum cpuhp_state lttng_hp_prepare;
This page took 0.039734 seconds and 4 git commands to generate.