Implement extensible LTTNG_KERNEL_ABI_COUNTER_EVENT ABI
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 24 Mar 2022 19:03:45 +0000 (15:03 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Jul 2024 21:01:43 +0000 (17:01 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I427287757a8842ab163791a6b34918ce80adcf51

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

index ac5469edc7af106e96a959a2dc756a2509d956e2..2ec5d6d0fbdd9275b0b21ea20cc37388012c4e95 100644 (file)
@@ -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 {
index 21ab79262271e24c9a429c9f0ee54962acaaf5f2..9f2f1605e02aa82b70d2cc64562511bce18e63ba 100644 (file)
@@ -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),                                                          \
index 6471aa669e5f2072c744a6073c1f469718e082f8..ec5fc8fcb59741484577d067f3150e83da0e7fd8 100644 (file)
@@ -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;
index 277e8fc4f6c3c8884ee248f8e7c71ee64f47728c..b8b79a7e5be7d98cd7b87c05082461a4eb6b9cdf 100644 (file)
@@ -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)
index 2d5b6ac0cbe3cd3ff973b3419de059536b565125..4ff38a3efe7c132ba1fba5c1c753a4f56427d3b8 100644 (file)
@@ -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)
index 72dcbe400286e034f5bab11fe39e124f9fd8df58..8a6c6478d3b4bf9e75bd09489cebab80319efd1b 100644 (file)
@@ -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;
        }
index aef50c4682b038c060d2b5ce3868fec511172ced..3548052ff2d240a076ea5f31d78caf5fd9f15bd5 100644 (file)
@@ -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;
This page took 0.037261 seconds and 4 git commands to generate.