From 99f52fcce5865809584c1e022bca1409702ea292 Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Fri, 7 Aug 2020 17:04:05 -0400 Subject: [PATCH] Implement event notifier error counter Signed-off-by: Francis Deslauriers Signed-off-by: Mathieu Desnoyers Change-Id: I566d34ab92aaa642f50407d913b16c4a6b8479a2 --- include/lttng/abi.h | 75 ++++++- include/lttng/events.h | 28 +++ src/lttng-abi.c | 255 +++++++++++++++++++++++- src/lttng-event-notifier-notification.c | 21 +- src/lttng-events.c | 137 +++++++++++-- src/lttng-syscalls.c | 10 +- 6 files changed, 503 insertions(+), 23 deletions(-) diff --git a/include/lttng/abi.h b/include/lttng/abi.h index 071133f6..843acbe7 100644 --- a/include/lttng/abi.h +++ b/include/lttng/abi.h @@ -11,6 +11,7 @@ #define _LTTNG_ABI_H #include +#include /* * Major/minor version of ABI exposed to lttng tools. Major number @@ -140,10 +141,69 @@ struct lttng_kernel_event { #define LTTNG_KERNEL_EVENT_NOTIFIER_PADDING1 16 struct lttng_kernel_event_notifier { struct lttng_kernel_event event; + uint64_t error_counter_index; char padding[LTTNG_KERNEL_EVENT_NOTIFIER_PADDING1]; } __attribute__((packed)); +enum lttng_kernel_counter_arithmetic { + LTTNG_KERNEL_COUNTER_ARITHMETIC_MODULAR = 1, +}; + +enum lttng_kernel_counter_bitness { + LTTNG_KERNEL_COUNTER_BITNESS_32 = 1, + LTTNG_KERNEL_COUNTER_BITNESS_64 = 2, +}; + +struct lttng_kernel_counter_dimension { + uint64_t size; + uint64_t underflow_index; + uint64_t overflow_index; + uint8_t has_underflow; + uint8_t has_overflow; +} __attribute__((packed)); + +#define LTTNG_KERNEL_COUNTER_DIMENSION_MAX 4 +struct lttng_kernel_counter_conf { + uint32_t arithmetic; /* enum lttng_kernel_counter_arithmetic */ + uint32_t bitness; /* enum lttng_kernel_counter_bitness */ + uint32_t number_dimensions; + int64_t global_sum_step; + struct lttng_kernel_counter_dimension dimensions[LTTNG_KERNEL_COUNTER_DIMENSION_MAX]; +} __attribute__((packed)); + +struct lttng_kernel_counter_index { + uint32_t number_dimensions; + uint64_t dimension_indexes[LTTNG_KERNEL_COUNTER_DIMENSION_MAX]; +} __attribute__((packed)); + +struct lttng_kernel_counter_value { + int64_t value; + uint8_t underflow; + uint8_t overflow; +} __attribute__((packed)); + +#define LTTNG_KERNEL_COUNTER_READ_PADDING 32 +struct lttng_kernel_counter_read { + struct lttng_kernel_counter_index index; + int32_t cpu; /* -1 for global counter, >= 0 for specific cpu. */ + struct lttng_kernel_counter_value value; /* output */ + char padding[LTTNG_KERNEL_COUNTER_READ_PADDING]; +} __attribute__((packed)); + +#define LTTNG_KERNEL_COUNTER_AGGREGATE_PADDING 32 +struct lttng_kernel_counter_aggregate { + struct lttng_kernel_counter_index index; + struct lttng_kernel_counter_value value; /* output */ + char padding[LTTNG_KERNEL_COUNTER_AGGREGATE_PADDING]; +} __attribute__((packed)); + +#define LTTNG_KERNEL_COUNTER_CLEAR_PADDING 32 +struct lttng_kernel_counter_clear { + struct lttng_kernel_counter_index index; + char padding[LTTNG_KERNEL_COUNTER_CLEAR_PADDING]; +} __attribute__((packed)); + #define LTTNG_KERNEL_EVENT_NOTIFIER_NOTIFICATION_PADDING 32 struct lttng_kernel_event_notifier_notification { uint64_t token; @@ -329,11 +389,15 @@ struct lttng_kernel_tracker_args { #define LTTNG_KERNEL_CONTEXT \ _IOW(0xF6, 0x71, struct lttng_kernel_context) -/* Event, Event notifier, Channel and Session ioctl */ +/* Event, Event notifier, Channel, Counter and Session ioctl */ /* lttng/abi-old.h reserve 0x80 and 0x81. */ #define LTTNG_KERNEL_ENABLE _IO(0xF6, 0x82) #define LTTNG_KERNEL_DISABLE _IO(0xF6, 0x83) +/* Trigger group and session ioctl */ +#define LTTNG_KERNEL_COUNTER \ + _IOW(0xF6, 0x84, struct lttng_kernel_counter_conf) + /* Event and Event notifier FD ioctl */ #define LTTNG_KERNEL_FILTER _IO(0xF6, 0x90) #define LTTNG_KERNEL_ADD_CALLSITE _IO(0xF6, 0x91) @@ -355,6 +419,15 @@ struct lttng_kernel_tracker_args { /* Event notifier file descriptor ioctl */ #define LTTNG_KERNEL_CAPTURE _IO(0xF6, 0xB8) +/* Counter file descriptor ioctl */ +#define LTTNG_KERNEL_COUNTER_READ \ + _IOWR(0xF6, 0xC0, struct lttng_kernel_counter_read) +#define LTTNG_KERNEL_COUNTER_AGGREGATE \ + _IOWR(0xF6, 0xC1, struct lttng_kernel_counter_aggregate) +#define LTTNG_KERNEL_COUNTER_CLEAR \ + _IOW(0xF6, 0xC2, struct lttng_kernel_counter_clear) + + /* * LTTng-specific ioctls for the lib ringbuffer. * diff --git a/include/lttng/events.h b/include/lttng/events.h index 7b3b1857..b4c5372a 100644 --- a/include/lttng/events.h +++ b/include/lttng/events.h @@ -356,6 +356,7 @@ struct lttng_event { struct lttng_event_notifier { enum lttng_event_type evtype; /* First field. */ uint64_t user_token; + uint64_t error_counter_index; int enabled; int registered; /* has reg'd tracepoint probe */ const struct lttng_event_desc *desc; @@ -426,6 +427,7 @@ struct lttng_event_enabler { struct lttng_event_notifier_enabler { struct lttng_enabler base; + uint64_t error_counter_index; struct list_head node; /* List of event_notifier enablers */ struct lttng_event_notifier_group *group; @@ -675,6 +677,14 @@ struct lttng_session { char creation_time[LTTNG_KERNEL_SESSION_CREATION_TIME_ISO8601_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_event_notifier_group { struct file *file; /* File associated to event notifier group */ struct file *notif_file; /* File used to expose notifications to userspace. */ @@ -759,7 +769,23 @@ int lttng_session_metadata_regenerate(struct lttng_session *session); int lttng_session_statedump(struct lttng_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, + const size_t *dimension_indexes, int32_t cpu, + int64_t *val, bool *overflow, bool *underflow); +int lttng_kernel_counter_aggregate(struct lttng_counter *counter, + const size_t *dimension_indexes, int64_t *val, + bool *overflow, bool *underflow); +int lttng_kernel_counter_clear(struct lttng_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( + struct file *event_notifier_group_file, + const struct lttng_kernel_counter_conf *error_counter_conf); void lttng_event_notifier_group_destroy( struct lttng_event_notifier_group *event_notifier_group); @@ -795,6 +821,7 @@ struct lttng_event *lttng_event_compat_old_create(struct lttng_channel *chan, struct lttng_event_notifier *lttng_event_notifier_create( const struct lttng_event_desc *event_notifier_desc, uint64_t id, + uint64_t error_counter_idx, struct lttng_event_notifier_group *event_notifier_group, struct lttng_kernel_event_notifier *event_notifier_param, void *filter, @@ -802,6 +829,7 @@ struct lttng_event_notifier *lttng_event_notifier_create( struct lttng_event_notifier *_lttng_event_notifier_create( const struct lttng_event_desc *event_notifier_desc, uint64_t id, + uint64_t error_counter_idx, struct lttng_event_notifier_group *event_notifier_group, struct lttng_kernel_event_notifier *event_notifier_param, void *filter, diff --git a/src/lttng-abi.c b/src/lttng-abi.c index 344f18c2..a9beda75 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -69,6 +69,17 @@ static struct file_operations lttng_stream_ring_buffer_file_operations; static int put_u64(uint64_t val, unsigned long arg); static int put_u32(uint32_t val, unsigned long arg); +static int validate_zeroed_padding(char *p, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (p[i]) + return -1; + } + return 0; +} + /* * Teardown management: opened file descriptors keep a refcount on the module, * so it can only exit when all file descriptors are closed. @@ -595,6 +606,135 @@ int lttng_abi_session_set_creation_time(struct lttng_session *session, return 0; } +static +int lttng_counter_release(struct inode *inode, struct file *file) +{ + struct lttng_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); + } + + return 0; +} + +static +long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct lttng_counter *counter = file->private_data; + size_t indexes[LTTNG_KERNEL_COUNTER_DIMENSION_MAX] = { 0 }; + int i; + + switch (cmd) { + case LTTNG_KERNEL_COUNTER_READ: + { + struct lttng_kernel_counter_read local_counter_read; + struct lttng_kernel_counter_read __user *ucounter_read = + (struct lttng_kernel_counter_read __user *) arg; + bool overflow, underflow; + int64_t value; + int32_t cpu; + int ret; + + if (copy_from_user(&local_counter_read, ucounter_read, + sizeof(local_counter_read))) + return -EFAULT; + if (validate_zeroed_padding(local_counter_read.padding, + sizeof(local_counter_read.padding))) + 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]; + cpu = local_counter_read.cpu; + + ret = lttng_kernel_counter_read(counter, indexes, cpu, &value, + &overflow, &underflow); + if (ret) + return ret; + local_counter_read.value.value = value; + local_counter_read.value.overflow = overflow; + local_counter_read.value.underflow = underflow; + + if (copy_to_user(&ucounter_read->value, &local_counter_read.value, + sizeof(local_counter_read.value))) + return -EFAULT; + + return 0; + } + case LTTNG_KERNEL_COUNTER_AGGREGATE: + { + struct lttng_kernel_counter_aggregate local_counter_aggregate; + struct lttng_kernel_counter_aggregate __user *ucounter_aggregate = + (struct lttng_kernel_counter_aggregate __user *) arg; + bool overflow, underflow; + int64_t value; + int ret; + + if (copy_from_user(&local_counter_aggregate, ucounter_aggregate, + sizeof(local_counter_aggregate))) + return -EFAULT; + if (validate_zeroed_padding(local_counter_aggregate.padding, + sizeof(local_counter_aggregate.padding))) + 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]; + + ret = lttng_kernel_counter_aggregate(counter, indexes, &value, + &overflow, &underflow); + if (ret) + return ret; + local_counter_aggregate.value.value = value; + local_counter_aggregate.value.overflow = overflow; + local_counter_aggregate.value.underflow = underflow; + + if (copy_to_user(&ucounter_aggregate->value, &local_counter_aggregate.value, + sizeof(local_counter_aggregate.value))) + return -EFAULT; + + return 0; + } + case LTTNG_KERNEL_COUNTER_CLEAR: + { + struct lttng_kernel_counter_clear local_counter_clear; + struct lttng_kernel_counter_clear __user *ucounter_clear = + (struct lttng_kernel_counter_clear __user *) arg; + + if (copy_from_user(&local_counter_clear, ucounter_clear, + sizeof(local_counter_clear))) + return -EFAULT; + if (validate_zeroed_padding(local_counter_clear.padding, + sizeof(local_counter_clear.padding))) + 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]; + + return lttng_kernel_counter_clear(counter, indexes); + } + default: + WARN_ON_ONCE(1); + return -ENOSYS; + } +} + +static const struct file_operations lttng_counter_fops = { + .owner = THIS_MODULE, + .release = lttng_counter_release, + .unlocked_ioctl = lttng_counter_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = lttng_counter_ioctl, +#endif +}; + + static enum tracker_type get_tracker_type(struct lttng_kernel_tracker_args *tracker) { @@ -1902,7 +2042,9 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file, * It will stay invariant for the rest of the session. */ event_notifier = lttng_event_notifier_create(NULL, - event_notifier_param->event.token, event_notifier_group, + event_notifier_param->event.token, + event_notifier_param->error_counter_index, + event_notifier_group, event_notifier_param, NULL, event_notifier_param->event.instrumentation); WARN_ON_ONCE(!event_notifier); @@ -1927,6 +2069,106 @@ inval_instr: return ret; } +static +long lttng_abi_event_notifier_group_create_error_counter( + struct file *event_notifier_group_file, + const struct lttng_kernel_counter_conf *error_counter_conf) +{ + int counter_fd, ret; + char *counter_transport_name; + size_t counter_len; + struct lttng_counter *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; + + if (error_counter_conf->arithmetic != LTTNG_KERNEL_COUNTER_ARITHMETIC_MODULAR) { + printk(KERN_ERR "LTTng: event_notifier: Error counter of the wrong arithmetic type.\n"); + return -EINVAL; + } + + if (error_counter_conf->number_dimensions != 1) { + printk(KERN_ERR "LTTng: event_notifier: Error counter has more than one dimension.\n"); + return -EINVAL; + } + + switch (error_counter_conf->bitness) { + case LTTNG_KERNEL_COUNTER_BITNESS_64: + counter_transport_name = "counter-per-cpu-64-modular"; + break; + case LTTNG_KERNEL_COUNTER_BITNESS_32: + counter_transport_name = "counter-per-cpu-32-modular"; + break; + default: + return -EINVAL; + } + + /* + * Lock sessions to provide mutual exclusion against concurrent + * modification of event_notifier group, which would result in + * overwriting the error counter if set concurrently. + */ + lttng_lock_sessions(); + + if (event_notifier_group->error_counter) { + printk(KERN_ERR "Error counter already created in event_notifier group\n"); + ret = -EBUSY; + goto fd_error; + } + + counter_fd = lttng_get_unused_fd(); + if (counter_fd < 0) { + ret = counter_fd; + goto fd_error; + } + + counter_file = anon_inode_getfile("[lttng_counter]", + <tng_counter_fops, + NULL, O_RDONLY); + if (IS_ERR(counter_file)) { + ret = PTR_ERR(counter_file); + goto file_error; + } + + counter_len = error_counter_conf->dimensions[0].size; + + 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) { + ret = -EINVAL; + goto counter_error; + } + + event_notifier_group->error_counter = counter; + event_notifier_group->error_counter_len = counter_len; + + counter->file = counter_file; + counter->owner = event_notifier_group->file; + counter_file->private_data = counter; + /* Ownership transferred. */ + counter = NULL; + + fd_install(counter_fd, counter_file); + lttng_unlock_sessions(); + + return counter_fd; + +counter_error: + atomic_long_dec(&event_notifier_group_file->f_count); +refcount_error: + fput(counter_file); +file_error: + put_unused_fd(counter_fd); +fd_error: + lttng_unlock_sessions(); + return ret; +} + static long lttng_event_notifier_group_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1946,6 +2188,17 @@ long lttng_event_notifier_group_ioctl(struct file *file, unsigned int cmd, return -EFAULT; return lttng_abi_create_event_notifier(file, &uevent_notifier_param); } + case LTTNG_KERNEL_COUNTER: + { + struct lttng_kernel_counter_conf uerror_counter_conf; + + if (copy_from_user(&uerror_counter_conf, + (struct lttng_kernel_counter_conf __user *) arg, + sizeof(uerror_counter_conf))) + return -EFAULT; + return lttng_abi_event_notifier_group_create_error_counter(file, + &uerror_counter_conf); + } default: return -ENOIOCTLCMD; } diff --git a/src/lttng-event-notifier-notification.c b/src/lttng-event-notifier-notification.c index b67af11a..82424e8f 100644 --- a/src/lttng-event-notifier-notification.c +++ b/src/lttng-event-notifier-notification.c @@ -347,6 +347,23 @@ end: return ret; } +static +void record_error(struct lttng_event_notifier *event_notifier) +{ + + struct lttng_event_notifier_group *event_notifier_group = event_notifier->group; + size_t dimension_index[1]; + int ret; + + dimension_index[0] = event_notifier->error_counter_index; + + ret = event_notifier_group->error_counter->ops->counter_add( + event_notifier_group->error_counter->counter, + dimension_index, 1); + if (ret) + WARN_ON_ONCE(1); +} + static void notification_send(struct lttng_event_notifier_notification *notif, struct lttng_event_notifier *event_notifier) @@ -375,9 +392,7 @@ void notification_send(struct lttng_event_notifier_notification *notif, lttng_alignof(kernel_notif), -1); ret = event_notifier_group->ops->event_reserve(&ctx, 0); if (ret < 0) { - //TODO: error handling with counter maps - //silently drop for now. - WARN_ON_ONCE(1); + record_error(event_notifier); return; } diff --git a/src/lttng-events.c b/src/lttng-events.c index 012f2245..9f683db1 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -198,6 +198,61 @@ err: return NULL; } +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; +} + +struct lttng_counter *lttng_kernel_counter_create( + const char *counter_transport_name, + size_t number_dimensions, const size_t *dimensions_sizes) +{ + struct lttng_counter *counter = NULL; + struct lttng_counter_transport *counter_transport = NULL; + + counter_transport = lttng_counter_transport_find(counter_transport_name); + if (!counter_transport) { + printk(KERN_WARNING "LTTng: counter transport %s not found.\n", + counter_transport_name); + goto notransport; + } + if (!try_module_get(counter_transport->owner)) { + printk(KERN_WARNING "LTTng: Can't lock counter transport module.\n"); + goto notransport; + } + + counter = lttng_kvzalloc(sizeof(struct lttng_counter), GFP_KERNEL); + if (!counter) + goto nomem; + + /* 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; + } + + return counter; + +create_error: + lttng_kvfree(counter); +nomem: + if (counter_transport) + module_put(counter_transport->owner); +notransport: + return NULL; +} + struct lttng_event_notifier_group *lttng_event_notifier_group_create(void) { struct lttng_transport *transport = NULL; @@ -355,6 +410,14 @@ void lttng_event_notifier_group_destroy( &event_notifier_group->event_notifiers_head, list) _lttng_event_notifier_destroy(event_notifier); + 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; + } + event_notifier_group->ops->channel_destroy(event_notifier_group->chan); module_put(event_notifier_group->transport->owner); list_del(&event_notifier_group->node); @@ -760,17 +823,6 @@ 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. @@ -1013,7 +1065,8 @@ full: struct lttng_event_notifier *_lttng_event_notifier_create( const struct lttng_event_desc *event_desc, - uint64_t token, struct lttng_event_notifier_group *event_notifier_group, + uint64_t token, uint64_t error_counter_index, + struct lttng_event_notifier_group *event_notifier_group, struct lttng_kernel_event_notifier *event_notifier_param, void *filter, enum lttng_kernel_instrumentation itype) { @@ -1061,6 +1114,7 @@ struct lttng_event_notifier *_lttng_event_notifier_create( event_notifier->group = event_notifier_group; event_notifier->user_token = token; + event_notifier->error_counter_index = error_counter_index; event_notifier->num_captures = 0; event_notifier->filter = filter; event_notifier->instrumentation = itype; @@ -1177,6 +1231,35 @@ struct lttng_event_notifier *_lttng_event_notifier_create( list_add(&event_notifier->list, &event_notifier_group->event_notifiers_head); hlist_add_head(&event_notifier->hlist, head); + + /* + * Clear the error counter bucket. The sessiond keeps track of which + * bucket is currently in use. We trust it. + */ + if (event_notifier_group->error_counter) { + size_t dimension_index[1]; + + /* + * Check that the index is within the boundary of the counter. + */ + if (event_notifier->error_counter_index >= event_notifier_group->error_counter_len) { + printk(KERN_INFO "LTTng: event_notifier: Error counter index out-of-bound: counter-len=%zu, index=%llu\n", + event_notifier_group->error_counter_len, event_notifier->error_counter_index); + ret = -EINVAL; + goto register_error; + } + + dimension_index[0] = event_notifier->error_counter_index; + ret = event_notifier_group->error_counter->ops->counter_clear( + event_notifier_group->error_counter->counter, + dimension_index); + if (ret) { + printk(KERN_INFO "LTTng: event_notifier: Unable to clear error counter bucket %llu\n", + event_notifier->error_counter_index); + goto register_error; + } + } + return event_notifier; register_error: @@ -1187,6 +1270,28 @@ type_error: return ERR_PTR(ret); } +int lttng_kernel_counter_read(struct lttng_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, + cpu, val, overflow, underflow); +} + +int lttng_kernel_counter_aggregate(struct lttng_counter *counter, + const size_t *dim_indexes, int64_t *val, + bool *overflow, bool *underflow) +{ + return counter->ops->counter_aggregate(counter->counter, dim_indexes, + val, overflow, underflow); +} + +int lttng_kernel_counter_clear(struct lttng_counter *counter, + const size_t *dim_indexes) +{ + return counter->ops->counter_clear(counter->counter, dim_indexes); +} + struct lttng_event *lttng_event_create(struct lttng_channel *chan, struct lttng_kernel_event *event_param, void *filter, @@ -1204,7 +1309,8 @@ struct lttng_event *lttng_event_create(struct lttng_channel *chan, struct lttng_event_notifier *lttng_event_notifier_create( const struct lttng_event_desc *event_desc, - uint64_t id, struct lttng_event_notifier_group *event_notifier_group, + uint64_t id, uint64_t error_counter_index, + struct lttng_event_notifier_group *event_notifier_group, struct lttng_kernel_event_notifier *event_notifier_param, void *filter, enum lttng_kernel_instrumentation itype) { @@ -1212,7 +1318,8 @@ struct lttng_event_notifier *lttng_event_notifier_create( mutex_lock(&sessions_mutex); event_notifier = _lttng_event_notifier_create(event_desc, id, - event_notifier_group, event_notifier_param, filter, itype); + error_counter_index, event_notifier_group, + event_notifier_param, filter, itype); mutex_unlock(&sessions_mutex); return event_notifier; } @@ -1942,6 +2049,7 @@ void lttng_create_tracepoint_event_notifier_if_missing(struct lttng_event_notifi */ event_notifier = _lttng_event_notifier_create(desc, event_notifier_enabler->base.user_token, + event_notifier_enabler->error_counter_index, event_notifier_group, NULL, NULL, LTTNG_KERNEL_TRACEPOINT); if (IS_ERR(event_notifier)) { @@ -2342,6 +2450,7 @@ struct lttng_event_notifier_enabler *lttng_event_notifier_enabler_create( INIT_LIST_HEAD(&event_notifier_enabler->base.filter_bytecode_head); INIT_LIST_HEAD(&event_notifier_enabler->capture_bytecode_head); + event_notifier_enabler->error_counter_index = event_notifier_param->error_counter_index; event_notifier_enabler->num_captures = 0; memcpy(&event_notifier_enabler->base.event_param, &event_notifier_param->event, diff --git a/src/lttng-syscalls.c b/src/lttng-syscalls.c index 14650835..41e10be0 100644 --- a/src/lttng-syscalls.c +++ b/src/lttng-syscalls.c @@ -1402,6 +1402,7 @@ int create_unknown_event_notifier( struct lttng_event_notifier_group *group = event_notifier_enabler->group; struct lttng_kernel_event_notifier event_notifier_param; uint64_t user_token = event_notifier_enabler->base.user_token; + uint64_t error_counter_index = event_notifier_enabler->error_counter_index; struct lttng_enabler *base_enabler = lttng_event_notifier_enabler_as_enabler( event_notifier_enabler); struct hlist_head *unknown_dispatch_list; @@ -1464,7 +1465,7 @@ int create_unknown_event_notifier( event_notifier_param.event.u.syscall.entryexit = entryexit; notifier = _lttng_event_notifier_create(desc, user_token, - group, &event_notifier_param, NULL, + error_counter_index, group, &event_notifier_param, NULL, event_notifier_param.event.instrumentation); if (IS_ERR(notifier)) { printk(KERN_INFO "Unable to create unknown notifier %s\n", @@ -1487,6 +1488,7 @@ static int create_matching_event_notifiers( struct lttng_event_notifier_group *group = event_notifier_enabler->group; const struct lttng_event_desc *desc; uint64_t user_token = event_notifier_enabler->base.user_token; + uint64_t error_counter_index = event_notifier_enabler->error_counter_index; unsigned int i; int ret = 0; @@ -1544,9 +1546,9 @@ static int create_matching_event_notifiers( event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL; - event_notifier = _lttng_event_notifier_create(desc, user_token, group, - &event_notifier_param, filter, - event_notifier_param.event.instrumentation); + event_notifier = _lttng_event_notifier_create(desc, user_token, + error_counter_index, group, &event_notifier_param, + filter, event_notifier_param.event.instrumentation); if (IS_ERR(event_notifier)) { printk(KERN_INFO "Unable to create event_notifier %s\n", desc->name); -- 2.34.1