Implement counter maps (for listing)
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 24 Feb 2022 20:42:56 +0000 (15:42 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Jul 2024 20:58:48 +0000 (16:58 -0400)
Also wire up LTTNG_KERNEL_ABI_SYSCALL_MASK in lttng_counter_ioctl.

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

include/lttng/events-internal.h
src/lttng-abi.c
src/lttng-events.c

index 9e516b2c889834c7842489e82fff6c68fefeb2a4..e79847fe24f52c53da85cdfc0105ed21207d8988 100644 (file)
@@ -256,6 +256,19 @@ struct lttng_kernel_channel_counter_ops_private {
                        size_t *max_nr_elem);   /* array of size nr_dimensions */
 };
 
+struct lttng_counter_map_descriptor {
+       uint64_t user_token;
+       size_t array_index;
+       char key[LTTNG_KERNEL_ABI_COUNTER_KEY_LEN];
+};
+
+struct lttng_counter_map {
+       struct lttng_counter_map_descriptor *descriptors;
+       size_t nr_descriptors;
+       size_t alloc_len;
+       struct mutex lock;              /* counter map lock */
+};
+
 struct lttng_kernel_channel_counter_private {
        struct lttng_kernel_channel_common_private parent;
 
@@ -263,6 +276,8 @@ struct lttng_kernel_channel_counter_private {
        struct lib_counter *counter;
        struct lttng_kernel_channel_counter_ops *ops;
 
+       struct lttng_counter_map map;
+
        /* Owned either by session or event notifier group. */
 
        /* Session or event notifier group file owner. */
@@ -491,19 +506,6 @@ struct lttng_kernel_channel_buffer_ops_private {
                        uint64_t *id);
 };
 
-struct lttng_counter_map_descriptor {
-       uint64_t user_token;
-       size_t array_index;
-       char key[LTTNG_KERNEL_ABI_COUNTER_KEY_LEN];
-};
-
-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
 #define LTTNG_EVENT_HT_SIZE            (1U << LTTNG_EVENT_HT_BITS)
 
index f03796fb4e45b6773b93c5ec812bbf542f800e31..b94f34cbe963fc0205fb1e968ff84a9148a2ea64 100644 (file)
@@ -764,6 +764,55 @@ long lttng_counter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                return lttng_channel_enable(&counter->parent);
        case LTTNG_KERNEL_ABI_DISABLE:
                return lttng_channel_disable(&counter->parent);
+       case LTTNG_KERNEL_ABI_SYSCALL_MASK:
+               return lttng_syscall_table_get_active_mask(&counter->priv->parent.syscall_table,
+                       (struct lttng_kernel_abi_syscall_mask __user *) arg);
+       case LTTNG_KERNEL_ABI_COUNTER_MAP_NR_DESCRIPTORS:
+       {
+               uint64_t __user *user_nr_descriptors = (uint64_t __user *) arg;
+               uint64_t nr_descriptors;
+
+               mutex_lock(&counter->priv->map.lock);
+               nr_descriptors = counter->priv->map.nr_descriptors;
+               mutex_unlock(&counter->priv->map.lock);
+               return put_user(nr_descriptors, user_nr_descriptors);
+       }
+       case LTTNG_KERNEL_ABI_COUNTER_MAP_DESCRIPTOR:
+       {
+               struct lttng_kernel_abi_counter_map_descriptor __user *user_descriptor =
+                       (struct lttng_kernel_abi_counter_map_descriptor __user *) arg;
+               struct lttng_kernel_abi_counter_map_descriptor local_descriptor;
+               struct lttng_counter_map_descriptor *kernel_descriptor;
+               int ret;
+
+               if (copy_from_user(&local_descriptor, user_descriptor,
+                                       sizeof(local_descriptor)))
+                       return -EFAULT;
+               if (validate_zeroed_padding(local_descriptor.padding,
+                               sizeof(local_descriptor.padding)))
+                       return -EINVAL;
+
+               mutex_lock(&counter->priv->map.lock);
+               if (local_descriptor.descriptor_index >= counter->priv->map.nr_descriptors) {
+                       ret = -EOVERFLOW;
+                       goto map_descriptor_error_unlock;
+               }
+               kernel_descriptor = &counter->priv->map.descriptors[local_descriptor.descriptor_index];
+               local_descriptor.user_token = kernel_descriptor->user_token;
+               local_descriptor.array_index = kernel_descriptor->array_index;
+               memcpy(local_descriptor.key, kernel_descriptor->key, LTTNG_KERNEL_ABI_COUNTER_KEY_LEN);
+               mutex_unlock(&counter->priv->map.lock);
+
+               if (copy_to_user(user_descriptor, &local_descriptor,
+                                       sizeof(local_descriptor)))
+                       return -EFAULT;
+
+               return 0;
+
+       map_descriptor_error_unlock:
+               mutex_unlock(&counter->priv->map.lock);
+               return ret;
+       }
        default:
                return -ENOSYS;
        }
index 640d9d3a9b24195f4e3a0e53131037ff3db864a0..89a72e66cb6c28706a087a156dc40955452bbb9a 100644 (file)
@@ -262,6 +262,7 @@ struct lttng_kernel_channel_counter *lttng_kernel_counter_create(
        counter->ops = &counter_transport->ops;
        counter->priv->parent.coalesce_hits = coalesce_hits;
        counter->priv->transport = counter_transport;
+       mutex_init(&counter->priv->map.lock);
 
        return counter;
 
@@ -278,6 +279,7 @@ 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);
        module_put(counter_transport->owner);
 }
 
@@ -1303,6 +1305,73 @@ bool lttng_event_enabler_event_name_key_match_event(struct lttng_event_enabler_c
        }
 }
 
+static
+int lttng_counter_append_descriptor(struct lttng_kernel_channel_counter *counter,
+               uint64_t user_token,
+               size_t index,
+               const char *key)
+{
+       struct lttng_counter_map *map = &counter->priv->map;
+       struct lttng_counter_map_descriptor *last;
+       int ret = 0;
+
+       if (strlen(key) >= LTTNG_KERNEL_ABI_COUNTER_KEY_LEN) {
+               WARN_ON_ONCE(1);
+               return -EOVERFLOW;
+       }
+       mutex_lock(&map->lock);
+       if (map->nr_descriptors == map->alloc_len) {
+               struct lttng_counter_map_descriptor *new_table, *old_table;
+               size_t old_len = map->nr_descriptors;
+               size_t new_len = max_t(size_t, old_len + 1, map->alloc_len * 2);
+
+               old_table = map->descriptors;
+               new_table = lttng_kvzalloc(sizeof(struct lttng_counter_map_descriptor) * new_len,
+                               GFP_KERNEL);
+               if (!new_table) {
+                       ret = -ENOMEM;
+                       goto unlock;
+               }
+
+               if (old_table)
+                       memcpy(new_table, old_table, old_len * sizeof(struct lttng_counter_map_descriptor));
+
+               map->descriptors = new_table;
+               map->alloc_len = new_len;
+               lttng_kvfree(old_table);
+       }
+       last = &map->descriptors[map->nr_descriptors++];
+       last->user_token = user_token;
+       last->array_index = index;
+       strcpy(last->key, key);
+unlock:
+       mutex_unlock(&map->lock);
+       return ret;
+}
+
+static
+int lttng_append_event_to_channel_map(struct lttng_event_enabler_common *event_enabler,
+               struct lttng_kernel_event_common *event,
+               const char *event_name)
+{
+       struct lttng_event_counter_enabler *event_counter_enabler;
+       struct lttng_kernel_channel_counter *chan_counter;
+       struct lttng_kernel_event_counter *event_counter;
+       const char *name = "<UNKNOWN>";
+
+       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);
+       event_counter = container_of(event, struct lttng_kernel_event_counter, parent);
+       chan_counter = event_counter_enabler->chan;
+       if (event_counter->priv->key[0])
+               name = event_counter->priv->key;
+       else
+               name = event_name;
+       return lttng_counter_append_descriptor(chan_counter, event_enabler->user_token,
+                       event_counter->priv->parent.id, name);
+}
+
 /*
  * Supports event creation while tracing session is active.
  * Needs to be called with sessions mutex held.
@@ -1408,6 +1477,8 @@ struct lttng_kernel_event_common *_lttng_kernel_event_create(struct lttng_event_
                }
                ret = try_module_get(event->priv->desc->owner);
                WARN_ON_ONCE(!ret);
+               ret = lttng_append_event_to_channel_map(event_enabler, event, event_name);
+               WARN_ON_ONCE(ret);
                break;
 
        case LTTNG_KERNEL_ABI_KRETPROBE:
@@ -1459,6 +1530,10 @@ struct lttng_kernel_event_common *_lttng_kernel_event_create(struct lttng_event_
                        goto statedump_error;
                }
                list_add(&event_return->priv->node, event_list_head);
+               ret = lttng_append_event_to_channel_map(event_enabler, event, event_name);
+               WARN_ON_ONCE(ret);
+               ret = lttng_append_event_to_channel_map(event_enabler, event_return, event_name);
+               WARN_ON_ONCE(ret);
                break;
        }
 
@@ -1516,6 +1591,8 @@ struct lttng_kernel_event_common *_lttng_kernel_event_create(struct lttng_event_
                        goto register_error;
                ret = try_module_get(event->priv->desc->owner);
                WARN_ON_ONCE(!ret);
+               ret = lttng_append_event_to_channel_map(event_enabler, event, event_name);
+               WARN_ON_ONCE(ret);
                break;
 
        default:
@@ -2358,6 +2435,8 @@ int lttng_event_enabler_ref_events(struct lttng_event_enabler_common *event_enab
 
                enabler_ref = lttng_enabler_ref(&event_priv->enablers_ref_head, event_enabler);
                if (!enabler_ref) {
+                       int ret;
+
                        /*
                         * If no backward ref, create it.
                         * Add backward ref from event_notifier to enabler.
@@ -2368,6 +2447,10 @@ int lttng_event_enabler_ref_events(struct lttng_event_enabler_common *event_enab
 
                        enabler_ref->ref = event_enabler;
                        list_add(&enabler_ref->node, &event_priv->enablers_ref_head);
+
+                       ret = lttng_append_event_to_channel_map(event_enabler, event,
+                                       event->priv->desc->event_name);
+                       WARN_ON_ONCE(ret);
                }
 
                lttng_event_enabler_init_event_filter(event_enabler, event);
This page took 0.031951 seconds and 4 git commands to generate.