From 7b0f1e69d49604c11deae2c4e7f2092274107e3d Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 24 Mar 2022 15:03:45 -0400 Subject: [PATCH] Implement extensible LTTNG_KERNEL_ABI_COUNTER_EVENT ABI Signed-off-by: Mathieu Desnoyers Change-Id: I427287757a8842ab163791a6b34918ce80adcf51 --- include/lttng/abi.h | 25 +- include/lttng/events-internal.h | 71 ++--- src/lttng-abi.c | 263 ++++++++++++++++--- src/lttng-counter-client-percpu-32-modular.c | 4 +- src/lttng-counter-client-percpu-64-modular.c | 4 +- src/lttng-events.c | 91 ++----- src/lttng-syscalls.c | 6 +- 7 files changed, 302 insertions(+), 162 deletions(-) diff --git a/include/lttng/abi.h b/include/lttng/abi.h index ac5469ed..2ec5d6d0 100644 --- a/include/lttng/abi.h +++ b/include/lttng/abi.h @@ -209,9 +209,6 @@ enum lttng_kernel_abi_counter_bitness { LTTNG_KERNEL_ABI_COUNTER_BITNESS_64 = 1, }; -//TODO: remove this define. -#define LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX 4 - struct lttng_kernel_abi_counter_key_string { uint32_t string_len; char str[]; /* Null-terminated string. */ @@ -227,36 +224,30 @@ struct lttng_kernel_abi_counter_map_descriptor { uint64_t key_ptr; /* pointer to struct lttng_kernel_abi_counter_key_string */ } __attribute__((packed)); -//TODO: new in 2.14, update. -#define LTTNG_KERNEL_ABI_KEY_ARG_PADDING1 60 -#define LTTNG_KERNEL_ABI_KEY_TOKEN_STRING_LEN_MAX 256 struct lttng_kernel_abi_key_token { - uint32_t type; /* enum lttng_kernel_abi_key_token_type */ + uint32_t type; /* enum lttng_kernel_abi_key_token_type */ union { uint64_t string_ptr; - char padding[LTTNG_KERNEL_ABI_KEY_ARG_PADDING1]; } arg; } __attribute__((packed)); -//TODO: new in 2.14, update. -#define LTTNG_KERNEL_ABI_NR_KEY_TOKEN 4 struct lttng_kernel_abi_counter_key_dimension { uint32_t nr_key_tokens; - struct lttng_kernel_abi_key_token key_tokens[LTTNG_KERNEL_ABI_NR_KEY_TOKEN]; + uint32_t elem_len; /* array stride (size of struct lttng_kernel_abi_key_token) */ + uint64_t ptr; /* pointer to array of struct lttng_kernel_abi_key_token */ } __attribute__((packed)); -//TODO: new in 2.14, update. struct lttng_kernel_abi_counter_key { - uint32_t nr_dimensions; - struct lttng_kernel_abi_counter_key_dimension key_dimensions[LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX]; + uint32_t number_dimensions; + uint32_t elem_len; /* array stride (size of struct lttng_kernel_abi_counter_key_dimension) */ + uint64_t ptr; /* pointer to array of struct lttng_kernel_abi_counter_key_dimension */ } __attribute__((packed)); -//TODO: new in 2.14, update. -#define LTTNG_KERNEL_ABI_COUNTER_EVENT_PADDING1 16 struct lttng_kernel_abi_counter_event { + uint32_t len; /* length of this structure */ + struct lttng_kernel_abi_event event; struct lttng_kernel_abi_counter_key key; - char padding[LTTNG_KERNEL_ABI_COUNTER_EVENT_PADDING1]; } __attribute__((packed)); enum lttng_kernel_abi_counter_dimension_flags { diff --git a/include/lttng/events-internal.h b/include/lttng/events-internal.h index 21ab7926..9f2f1605 100644 --- a/include/lttng/events-internal.h +++ b/include/lttng/events-internal.h @@ -25,32 +25,6 @@ enum lttng_enabler_format_type { LTTNG_ENABLER_FORMAT_NAME, }; -#define LTTNG_KEY_TOKEN_STRING_LEN_MAX LTTNG_KERNEL_ABI_KEY_TOKEN_STRING_LEN_MAX - -enum lttng_key_token_type { - LTTNG_KEY_TOKEN_STRING = 0, - LTTNG_KEY_TOKEN_EVENT_NAME = 1, -}; - -struct lttng_key_token { - enum lttng_key_token_type type; - union { - char string[LTTNG_KEY_TOKEN_STRING_LEN_MAX]; - } arg; -}; - -#define LTTNG_NR_KEY_TOKEN LTTNG_KERNEL_ABI_NR_KEY_TOKEN -struct lttng_counter_key_dimension { - size_t nr_key_tokens; - struct lttng_key_token key_tokens[LTTNG_NR_KEY_TOKEN]; -}; - -#define LTTNG_COUNTER_DIMENSION_MAX LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX -struct lttng_counter_key { - size_t nr_dimensions; - struct lttng_counter_key_dimension key_dimensions[LTTNG_COUNTER_DIMENSION_MAX]; -}; - enum lttng_kernel_event_enabler_type { LTTNG_EVENT_ENABLER_TYPE_RECORDER, LTTNG_EVENT_ENABLER_TYPE_NOTIFIER, @@ -158,12 +132,14 @@ struct lttng_kernel_event_recorder_private { unsigned int metadata_dumped:1; }; +#define LTTNG_KERNEL_COUNTER_KEY_LEN 256 + struct lttng_kernel_event_counter_private { struct lttng_kernel_event_session_common_private parent; struct lttng_kernel_event_counter *pub; /* Public event interface */ struct hlist_node hlist_key_node; /* node in events key hash table */ - char key[LTTNG_KEY_TOKEN_STRING_LEN_MAX]; + char key[LTTNG_KERNEL_COUNTER_KEY_LEN]; }; struct lttng_kernel_event_notifier_private { @@ -261,7 +237,6 @@ struct lttng_kernel_channel_counter_ops_private { size_t *max_nr_elem); /* array of size nr_dimensions */ }; -#define LTTNG_KERNEL_COUNTER_KEY_LEN 256 struct lttng_counter_map_descriptor { uint64_t user_token; size_t array_index; @@ -376,7 +351,7 @@ struct lttng_event_recorder_enabler { struct lttng_event_counter_enabler { struct lttng_event_enabler_session_common parent; struct lttng_kernel_channel_counter *chan; - struct lttng_counter_key key; + struct lttng_kernel_counter_key *key; }; struct lttng_event_notifier_enabler { @@ -627,6 +602,8 @@ enum lttng_kernel_counter_bitness { /* Internally, only 1 dimension is supported fow now. */ #define LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS 1 +/* Internally, only 16 tokens are supported for now. */ +#define LTTNG_KERNEL_COUNTER_MAX_TOKENS 16 struct lttng_kernel_counter_dimension { uint32_t flags; /* enum lttng_kernel_counter_dimension_flags */ @@ -643,6 +620,35 @@ struct lttng_kernel_counter_conf { struct lttng_kernel_counter_dimension dimension_array[LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS]; }; +enum lttng_key_token_type { + LTTNG_KEY_TOKEN_UNKNOWN = 0, /* Uninitialized. */ + + LTTNG_KEY_TOKEN_STRING = 1, + LTTNG_KEY_TOKEN_EVENT_NAME = 2, +}; + +struct lttng_key_token { + enum lttng_key_token_type type; + char *str; +}; + +struct lttng_kernel_counter_key_dimension { + size_t nr_key_tokens; + struct lttng_key_token *token_array; +}; + +struct lttng_kernel_counter_key { + size_t nr_dimensions; + struct lttng_kernel_counter_key_dimension dimension_array[LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS]; +}; + +struct lttng_kernel_counter_event { + struct lttng_kernel_abi_event event_param; + struct lttng_kernel_abi_event_ext event_param_ext; + + struct lttng_kernel_counter_key *counter_key; +}; + extern struct lttng_kernel_ctx *lttng_static_ctx; static inline @@ -1336,10 +1342,13 @@ bool lttng_event_enabler_event_name_key_match_event(struct lttng_event_enabler_c struct lttng_event_counter_enabler *lttng_event_counter_enabler_create( enum lttng_enabler_format_type format_type, struct lttng_kernel_abi_event *event_param, - const struct lttng_kernel_abi_counter_key *abi_key, - const struct lttng_counter_key *kernel_key, + struct lttng_kernel_counter_key *counter_key, struct lttng_kernel_channel_counter *chan); +int create_counter_key_from_kernel(struct lttng_kernel_counter_key **counter_key, + const struct lttng_kernel_counter_key *key); +void destroy_counter_key(struct lttng_kernel_counter_key *counter_key); + #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), \ diff --git a/src/lttng-abi.c b/src/lttng-abi.c index 6471aa66..ec5fc8fc 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -75,9 +75,7 @@ static int put_u32(uint32_t val, unsigned long arg); static int lttng_abi_create_event_counter_enabler(struct file *channel_file, - struct lttng_kernel_abi_event *event_param, - struct lttng_kernel_abi_event_ext *event_param_ext, - const struct lttng_kernel_abi_counter_key *key_param); + struct lttng_kernel_counter_event *counter_event); static long lttng_abi_session_create_counter( struct lttng_kernel_session *session, @@ -688,6 +686,199 @@ end: return 0; } +static +int create_counter_key_from_abi_key(struct lttng_kernel_counter_key **_counter_key, + struct lttng_kernel_abi_counter_key *abi_key) +{ + struct lttng_kernel_counter_key *counter_key; + uint32_t i, dimension_len, nr_dimensions; + struct lttng_kernel_abi_counter_key_dimension __user *udimension; + struct lttng_kernel_abi_counter_key_dimension kdimension = {}; + struct lttng_kernel_abi_key_token __user *utoken; + struct lttng_key_token *token_array; + uint32_t token_len, nr_tokens; + int ret = 0; + + nr_dimensions = abi_key->number_dimensions; + if (!nr_dimensions || nr_dimensions > LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS) + return -EINVAL; + counter_key = kzalloc(sizeof(*counter_key), GFP_KERNEL); + if (!counter_key) + return -ENOMEM; + counter_key->nr_dimensions = nr_dimensions; + dimension_len = abi_key->elem_len; + if (dimension_len > PAGE_SIZE) { + ret = -E2BIG; + goto error; + } + if (dimension_len < offsetofend(struct lttng_kernel_abi_counter_key_dimension, ptr)) { + ret = -EINVAL; + goto error; + } + /* Only a single dimension is supported. */ + WARN_ON_ONCE(nr_dimensions != 1); + udimension = (struct lttng_kernel_abi_counter_key_dimension __user *)(unsigned long)abi_key->ptr; + ret = lttng_copy_struct_from_user(&kdimension, sizeof(kdimension), udimension, dimension_len); + if (ret) + goto error; + nr_tokens = kdimension.nr_key_tokens; + if (nr_tokens > LTTNG_KERNEL_COUNTER_MAX_TOKENS) { + ret = -EINVAL; + goto error; + } + token_len = kdimension.elem_len; + if (token_len > PAGE_SIZE) { + ret = -E2BIG; + goto error; + } + token_array = kzalloc(nr_tokens * sizeof(*token_array), GFP_KERNEL); + if (!token_array) { + ret = -ENOMEM; + goto error; + } + counter_key->dimension_array[0].token_array = token_array; + counter_key->dimension_array[0].nr_key_tokens = nr_tokens; + utoken = (struct lttng_kernel_abi_key_token __user *)(unsigned long)kdimension.ptr; + for (i = 0; i < nr_tokens; i++) { + struct lttng_kernel_abi_key_token ktoken = {}; + struct lttng_key_token *key_token = &token_array[i]; + + ret = lttng_copy_struct_from_user(&ktoken, sizeof(ktoken), utoken, token_len); + if (ret) + goto error; + switch (ktoken.type) { + case LTTNG_KERNEL_ABI_KEY_TOKEN_STRING: + { + char __user *string_ptr = (char __user *)(unsigned long)ktoken.arg.string_ptr; + size_t string_len; + + key_token->type = LTTNG_KEY_TOKEN_STRING; + + string_len = strnlen_user(string_ptr, PAGE_SIZE); + if (!string_len || string_len > PAGE_SIZE) { + ret = -EINVAL; + goto error; + } + key_token->str = kzalloc(string_len, GFP_KERNEL); + if (!key_token->str) { + ret = -ENOMEM; + goto error; + } + ret = copy_from_user(key_token->str, string_ptr, string_len); + if (ret) + goto error; + if (key_token->str[string_len - 1] != '\0') { + ret = -EINVAL; + goto error; + } + break; + } + case LTTNG_KERNEL_ABI_KEY_TOKEN_EVENT_NAME: + key_token->type = LTTNG_KEY_TOKEN_EVENT_NAME; + break; + + case LTTNG_KERNEL_ABI_KEY_TOKEN_PROVIDER_NAME: + lttng_fallthrough; + default: + ret = -EINVAL; + goto error; + } + utoken = (struct lttng_kernel_abi_key_token __user *)((unsigned long)utoken + token_len); + } + *_counter_key = counter_key; + return 0; + +error: + destroy_counter_key(counter_key); + return ret; +} + +int create_counter_key_from_kernel(struct lttng_kernel_counter_key **_new_key, + const struct lttng_kernel_counter_key *src_key) +{ + struct lttng_kernel_counter_key *new_key; + int i, ret = 0; + + new_key = kzalloc(sizeof(*new_key), GFP_KERNEL); + if (!new_key) + return -ENOMEM; + new_key->nr_dimensions = src_key->nr_dimensions; + for (i = 0; i < src_key->nr_dimensions; i++) { + struct lttng_kernel_counter_key_dimension *new_dimension = &new_key->dimension_array[i]; + const struct lttng_kernel_counter_key_dimension *src_dimension = &src_key->dimension_array[i]; + uint32_t nr_tokens = src_dimension->nr_key_tokens; + int j; + + new_dimension->nr_key_tokens = nr_tokens; + new_dimension->token_array = kzalloc(nr_tokens * sizeof(*new_dimension->token_array), GFP_KERNEL); + if (!new_dimension->token_array) { + ret = -ENOMEM; + goto error; + } + for (j = 0; j < nr_tokens; j++) { + struct lttng_key_token *new_key_token = &new_dimension->token_array[j]; + struct lttng_key_token *src_key_token = &src_dimension->token_array[j]; + + switch (src_key_token->type) { + case LTTNG_KEY_TOKEN_STRING: + new_key_token->type = LTTNG_KEY_TOKEN_STRING; + new_key_token->str = kstrdup(src_key_token->str, GFP_KERNEL); + if (!new_key_token->str) { + ret = -ENOMEM; + goto error; + } + break; + case LTTNG_KEY_TOKEN_EVENT_NAME: + new_key_token->type = LTTNG_KEY_TOKEN_EVENT_NAME; + break; + + default: + ret = -EINVAL; + goto error; + } + } + } + *_new_key = new_key; + return 0; + +error: + destroy_counter_key(new_key); + return ret; +} + +void destroy_counter_key(struct lttng_kernel_counter_key *counter_key) +{ + int i; + + if (!counter_key) + return; + for (i = 0; i < counter_key->nr_dimensions; i++) { + struct lttng_kernel_counter_key_dimension *dimension = &counter_key->dimension_array[i]; + uint32_t nr_tokens = dimension->nr_key_tokens; + int j; + + for (j = 0; j < nr_tokens; j++) { + struct lttng_key_token *key_token = &dimension->token_array[j]; + + switch (key_token->type) { + case LTTNG_KEY_TOKEN_STRING: + kfree(key_token->str); + break; + + case LTTNG_KEY_TOKEN_EVENT_NAME: + lttng_fallthrough; + case LTTNG_KEY_TOKEN_UNKNOWN: + break; + + default: + WARN_ON_ONCE(1); + } + } + kfree(dimension->token_array); + } + kfree(counter_key); +} + static long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -918,32 +1109,41 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } return lttng_kernel_counter_clear(counter, indexes); } - case LTTNG_KERNEL_ABI_COUNTER_EVENT: //TODO: update to 2.14 ABI. + case LTTNG_KERNEL_ABI_COUNTER_EVENT: { - struct lttng_kernel_abi_counter_event *counter_event_param; - struct lttng_kernel_abi_counter_event __user *ucounter_event_param = + struct lttng_kernel_abi_counter_event __user *ucounter_event = (struct lttng_kernel_abi_counter_event __user *) arg; - struct lttng_kernel_abi_event *event_param; - struct lttng_kernel_abi_counter_key *key_param; - struct lttng_kernel_abi_event_ext event_param_ext = {}; - long ret; + struct lttng_kernel_abi_counter_event kcounter_event = {}; + struct lttng_kernel_counter_event *counter_event; + uint32_t len; + int ret; - counter_event_param = kzalloc(sizeof(*counter_event_param), GFP_KERNEL); - if (!counter_event_param) - return -ENOMEM; - if (copy_from_user(counter_event_param, ucounter_event_param, - sizeof(*counter_event_param))) - return -EFAULT; - if (validate_zeroed_padding(counter_event_param->padding, - sizeof(counter_event_param->padding))) - return -EINVAL; - event_param = &counter_event_param->event; - key_param = &counter_event_param->key; - ret = copy_user_event_param_ext(&event_param_ext, event_param); + ret = get_user(len, &ucounter_event->len); if (ret) return ret; - ret = lttng_abi_create_event_counter_enabler(file, event_param, &event_param_ext, key_param); - kfree(counter_event_param); + if (len > PAGE_SIZE) + return -E2BIG; + if (len < offsetofend(struct lttng_kernel_abi_counter_event, key)) + return -EINVAL; + counter_event = kzalloc(sizeof(*counter_event), GFP_KERNEL); + if (!counter_event) { + return -ENOMEM; + } + ret = lttng_copy_struct_from_user(&kcounter_event, sizeof(kcounter_event), + ucounter_event, len); + if (ret) + goto end_counter_event; + memcpy(&counter_event->event_param, &kcounter_event.event, sizeof(counter_event->event_param)); + ret = copy_user_event_param_ext(&counter_event->event_param_ext, &kcounter_event.event); + if (ret) + goto end_counter_event; + ret = create_counter_key_from_abi_key(&counter_event->counter_key, &kcounter_event.key); + if (ret) + goto end_counter_event; + ret = lttng_abi_create_event_counter_enabler(file, counter_event); + destroy_counter_key(counter_event->counter_key); + end_counter_event: + kfree(counter_event); return ret; } case LTTNG_KERNEL_ABI_ENABLE: @@ -2514,12 +2714,13 @@ fd_error: static int lttng_abi_create_event_counter_enabler(struct file *channel_file, - struct lttng_kernel_abi_event *event_param, - struct lttng_kernel_abi_event_ext *event_param_ext, - const struct lttng_kernel_abi_counter_key *key_param) + struct lttng_kernel_counter_event *counter_event) { const struct file_operations *fops; struct lttng_kernel_channel_counter *channel = channel_file->private_data; + struct lttng_kernel_abi_event *event_param = &counter_event->event_param; + struct lttng_kernel_abi_event_ext *event_param_ext = &counter_event->event_param_ext; + struct lttng_kernel_counter_key *counter_key = counter_event->counter_key; int event_fd, ret; struct file *event_file; void *priv; @@ -2599,10 +2800,10 @@ int lttng_abi_create_event_counter_enabler(struct file *channel_file, * we create the special star globbing enabler. */ event_enabler = lttng_event_counter_enabler_create(LTTNG_ENABLER_FORMAT_STAR_GLOB, - event_param, key_param, NULL, channel); + event_param, counter_key, channel); } else { event_enabler = lttng_event_counter_enabler_create(LTTNG_ENABLER_FORMAT_NAME, - event_param, key_param, NULL, channel); + event_param, counter_key, channel); } if (event_enabler) lttng_event_enabler_session_add(channel->parent.session, &event_enabler->parent); @@ -2617,7 +2818,7 @@ int lttng_abi_create_event_counter_enabler(struct file *channel_file, struct lttng_event_counter_enabler *event_enabler; event_enabler = lttng_event_counter_enabler_create(LTTNG_ENABLER_FORMAT_NAME, - event_param, key_param, NULL, channel); + event_param, counter_key, channel); if (event_enabler) lttng_event_enabler_session_add(channel->parent.session, &event_enabler->parent); priv = event_enabler; @@ -2630,7 +2831,7 @@ int lttng_abi_create_event_counter_enabler(struct file *channel_file, struct lttng_event_counter_enabler *event_enabler; event_enabler = lttng_event_counter_enabler_create(LTTNG_ENABLER_FORMAT_NAME, - event_param, key_param, NULL, channel); + event_param, counter_key, channel); if (!event_enabler) { ret = -ENOMEM; goto event_error; diff --git a/src/lttng-counter-client-percpu-32-modular.c b/src/lttng-counter-client-percpu-32-modular.c index 277e8fc4..b8b79a7e 100644 --- a/src/lttng-counter-client-percpu-32-modular.c +++ b/src/lttng-counter-client-percpu-32-modular.c @@ -26,11 +26,11 @@ static struct lttng_kernel_channel_counter *counter_create(size_t nr_dimensions, const struct lttng_kernel_counter_dimension *dimensions, int64_t global_sum_step) { - size_t max_nr_elem[LTTNG_COUNTER_DIMENSION_MAX], i; + size_t max_nr_elem[LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS], i; struct lttng_kernel_channel_counter *lttng_chan_counter; struct lib_counter *counter; - if (nr_dimensions > LTTNG_COUNTER_DIMENSION_MAX) + if (nr_dimensions > LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS) return NULL; for (i = 0; i < nr_dimensions; i++) { if ((dimensions[i].flags & LTTNG_KERNEL_COUNTER_DIMENSION_FLAG_UNDERFLOW) diff --git a/src/lttng-counter-client-percpu-64-modular.c b/src/lttng-counter-client-percpu-64-modular.c index 2d5b6ac0..4ff38a3e 100644 --- a/src/lttng-counter-client-percpu-64-modular.c +++ b/src/lttng-counter-client-percpu-64-modular.c @@ -26,11 +26,11 @@ static struct lttng_kernel_channel_counter *counter_create(size_t nr_dimensions, const struct lttng_kernel_counter_dimension *dimensions, int64_t global_sum_step) { - size_t max_nr_elem[LTTNG_COUNTER_DIMENSION_MAX], i; + size_t max_nr_elem[LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS], i; struct lttng_kernel_channel_counter *lttng_chan_counter; struct lib_counter *counter; - if (nr_dimensions > LTTNG_COUNTER_DIMENSION_MAX) + if (nr_dimensions > LTTNG_KERNEL_COUNTER_MAX_DIMENSIONS) return NULL; for (i = 0; i < nr_dimensions; i++) { if ((dimensions[i].flags & LTTNG_KERNEL_COUNTER_DIMENSION_FLAG_UNDERFLOW) diff --git a/src/lttng-events.c b/src/lttng-events.c index 72dcbe40..8a6c6478 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -280,8 +280,8 @@ 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); lttng_kvfree(counter->priv->map.descriptors); + counter->ops->priv->counter_destroy(counter); module_put(counter_transport->owner); } @@ -1184,29 +1184,28 @@ int format_event_key(struct lttng_event_enabler_common *event_enabler, char *key const char *event_name) { struct lttng_event_counter_enabler *event_counter_enabler; - const struct lttng_counter_key_dimension *dim; - size_t i, left = LTTNG_KEY_TOKEN_STRING_LEN_MAX; - const struct lttng_counter_key *key; + const struct lttng_kernel_counter_key_dimension *dim; + size_t i, left = LTTNG_KERNEL_COUNTER_KEY_LEN; + const struct lttng_kernel_counter_key *key; - if (event_enabler->enabler_type != LTTNG_EVENT_ENABLER_TYPE_COUNTER) { + if (event_enabler->enabler_type != LTTNG_EVENT_ENABLER_TYPE_COUNTER) return 0; - } event_counter_enabler = container_of(event_enabler, struct lttng_event_counter_enabler, parent.parent); - key = &event_counter_enabler->key; + key = event_counter_enabler->key; if (!key->nr_dimensions) return 0; /* Currently event keys can only be specified on a single dimension. */ if (key->nr_dimensions != 1) return -EINVAL; - dim = &key->key_dimensions[0]; + dim = &key->dimension_array[0]; for (i = 0; i < dim->nr_key_tokens; i++) { - const struct lttng_key_token *token = &dim->key_tokens[i]; + const struct lttng_key_token *token = &dim->token_array[i]; size_t token_len; const char *str; switch (token->type) { case LTTNG_KEY_TOKEN_STRING: - str = token->arg.string; + str = token->str; break; case LTTNG_KEY_TOKEN_EVENT_NAME: str = event_name; @@ -1381,7 +1380,7 @@ struct lttng_kernel_event_common *_lttng_kernel_event_create(struct lttng_event_ const struct lttng_kernel_event_desc *event_desc, struct lttng_kernel_event_pair *event_pair) { - char key_string[LTTNG_KEY_TOKEN_STRING_LEN_MAX] = { 0 }; + char key_string[LTTNG_KERNEL_COUNTER_KEY_LEN] = { 0 }; struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(event_enabler); struct lttng_event_ht *events_key_ht = lttng_get_events_key_ht_from_enabler(event_enabler); struct list_head *event_list_head = lttng_get_event_list_head_from_enabler(event_enabler); @@ -2609,62 +2608,6 @@ int lttng_fix_pending_event_notifiers(void) return 0; } -static -int copy_abi_counter_key(struct lttng_counter_key *key, - const struct lttng_kernel_abi_counter_key *key_param) -{ - size_t i, j, nr_dimensions; - - nr_dimensions = key_param->nr_dimensions; - if (nr_dimensions > LTTNG_KERNEL_ABI_COUNTER_DIMENSION_MAX) - return -EINVAL; - key->nr_dimensions = nr_dimensions; - for (i = 0; i < nr_dimensions; i++) { - const struct lttng_kernel_abi_counter_key_dimension *udim = - &key_param->key_dimensions[i]; - struct lttng_counter_key_dimension *dim = - &key->key_dimensions[i]; - size_t nr_key_tokens; - - nr_key_tokens = udim->nr_key_tokens; - if (!nr_key_tokens || nr_key_tokens > LTTNG_KERNEL_ABI_NR_KEY_TOKEN) - return -EINVAL; - dim->nr_key_tokens = nr_key_tokens; - for (j = 0; j < nr_key_tokens; j++) { - const struct lttng_kernel_abi_key_token *utoken = - &udim->key_tokens[j]; - struct lttng_key_token *token = - &dim->key_tokens[j]; - - switch (utoken->type) { - case LTTNG_KERNEL_ABI_KEY_TOKEN_STRING: - { - long ret; - - token->type = LTTNG_KERNEL_ABI_KEY_TOKEN_STRING; - ret = strncpy_from_user(token->arg.string, - (char __user *)(unsigned long)utoken->arg.string_ptr, - LTTNG_KERNEL_ABI_KEY_TOKEN_STRING_LEN_MAX); - if (ret < 0) - return -EFAULT; - if (!ret || ret == LTTNG_KERNEL_ABI_KEY_TOKEN_STRING_LEN_MAX) - return -EINVAL; - break; - } - case LTTNG_KERNEL_ABI_KEY_TOKEN_EVENT_NAME: - token->type = LTTNG_KERNEL_ABI_KEY_TOKEN_EVENT_NAME; - break; - case LTTNG_KERNEL_ABI_KEY_TOKEN_PROVIDER_NAME: - printk(KERN_ERR "LTTng: Provider name token not supported.\n"); - lttng_fallthrough; - default: - return -EINVAL; - } - } - } - return 0; -} - struct lttng_event_recorder_enabler *lttng_event_recorder_enabler_create( enum lttng_enabler_format_type format_type, struct lttng_kernel_abi_event *event_param, @@ -2691,8 +2634,7 @@ struct lttng_event_recorder_enabler *lttng_event_recorder_enabler_create( struct lttng_event_counter_enabler *lttng_event_counter_enabler_create( enum lttng_enabler_format_type format_type, struct lttng_kernel_abi_event *event_param, - const struct lttng_kernel_abi_counter_key *abi_key, - const struct lttng_counter_key *kernel_key, + struct lttng_kernel_counter_key *counter_key, struct lttng_kernel_channel_counter *chan) { struct lttng_event_counter_enabler *event_enabler; @@ -2707,13 +2649,9 @@ struct lttng_event_counter_enabler *lttng_event_counter_enabler_create( sizeof(event_enabler->parent.parent.event_param)); event_enabler->chan = chan; event_enabler->parent.chan = &chan->parent; - if (abi_key) { - if (copy_abi_counter_key(&event_enabler->key, abi_key)) { - kfree(event_enabler); - return NULL; - } - } else { - memcpy(&event_enabler->key, kernel_key, sizeof(*kernel_key)); + if (create_counter_key_from_kernel(&event_enabler->key, counter_key)) { + kfree(event_enabler); + return NULL; } /* ctx left NULL */ @@ -2849,6 +2787,7 @@ void lttng_event_enabler_destroy(struct lttng_event_enabler_common *event_enable struct lttng_event_counter_enabler *event_counter_enabler = container_of(event_enabler, struct lttng_event_counter_enabler, parent.parent); + destroy_counter_key(event_counter_enabler->key); kfree(event_counter_enabler); break; } diff --git a/src/lttng-syscalls.c b/src/lttng-syscalls.c index aef50c46..3548052f 100644 --- a/src/lttng-syscalls.c +++ b/src/lttng-syscalls.c @@ -665,7 +665,7 @@ void lttng_syscall_event_enabler_create_event(struct lttng_event_enabler_common ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL; ev.token = syscall_event_enabler->user_token; event_counter_enabler = lttng_event_counter_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, - NULL, &syscall_event_counter_enabler->key, syscall_event_counter_enabler->chan); + syscall_event_counter_enabler->key, syscall_event_counter_enabler->chan); WARN_ON_ONCE(!event_counter_enabler); if (!event_counter_enabler) return; @@ -700,7 +700,7 @@ void lttng_syscall_event_enabler_create_matching_syscall_table_events(struct ltt #endif /* iterate over all syscall and create event that match */ for (i = 0; i < table_len; i++) { - char key_string[LTTNG_KEY_TOKEN_STRING_LEN_MAX] = { 0 }; + char key_string[LTTNG_KERNEL_COUNTER_KEY_LEN] = { 0 }; struct lttng_kernel_event_common_private *event_priv; struct hlist_head *head; bool found = false; @@ -751,7 +751,7 @@ bool lttng_syscall_event_enabler_is_wildcard_all(struct lttng_event_enabler_comm static void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type) { - char key_string[LTTNG_KEY_TOKEN_STRING_LEN_MAX] = { 0 }; + char key_string[LTTNG_KERNEL_COUNTER_KEY_LEN] = { 0 }; struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(event_enabler); struct lttng_kernel_event_common_private *event_priv; const struct lttng_kernel_event_desc *desc; -- 2.34.1