From 750b05f22826af9bce23e915ca4b9d8a15754797 Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Wed, 5 Feb 2020 14:13:42 -0500 Subject: [PATCH] Implement event notifier group create Event notifier groups will contain the event notifiers. All event notifiers of a group will share the same ring buffer to save the tracer notifications. Signed-off-by: Francis Deslauriers Signed-off-by: Mathieu Desnoyers Change-Id: I7c38fbfd26517d00c8de38ca1981da623d570529 --- include/lttng/abi.h | 1 + include/lttng/events.h | 14 ++++++++ src/lttng-abi.c | 71 +++++++++++++++++++++++++++++++++++++++++ src/lttng-events.c | 72 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+) diff --git a/include/lttng/abi.h b/include/lttng/abi.h index 0e3b5d15..8ef9c112 100644 --- a/include/lttng/abi.h +++ b/include/lttng/abi.h @@ -264,6 +264,7 @@ struct lttng_kernel_tracker_args { #define LTTNG_KERNEL_SYSCALL_LIST _IO(0xF6, 0x4A) #define LTTNG_KERNEL_TRACER_ABI_VERSION \ _IOR(0xF6, 0x4B, struct lttng_kernel_tracer_abi_version) +#define LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_CREATE _IO(0xF6, 0x4C) /* Session FD ioctl */ /* lttng/abi-old.h reserve 0x50, 0x51, 0x52, and 0x53. */ diff --git a/include/lttng/events.h b/include/lttng/events.h index 06bde320..1e84000d 100644 --- a/include/lttng/events.h +++ b/include/lttng/events.h @@ -557,6 +557,16 @@ struct lttng_session { char creation_time[LTTNG_KERNEL_SESSION_CREATION_TIME_ISO8601_LEN]; }; +struct lttng_event_notifier_group { + struct file *file; /* File associated to event notifier group */ + struct list_head node; /* event notifier group list */ + struct lttng_ctx *ctx; /* Contexts for filters. */ + struct lttng_channel_ops *ops; + struct lttng_transport *transport; + struct channel *chan; /* Ring buffer channel for event notifier group. */ + struct lib_ring_buffer *buf; /* Ring buffer for event notifier group. */ +}; + struct lttng_metadata_cache { char *data; /* Metadata cache */ unsigned int cache_alloc; /* Metadata allocated size (bytes) */ @@ -592,6 +602,10 @@ 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_event_notifier_group *lttng_event_notifier_group_create(void); +void lttng_event_notifier_group_destroy( + struct lttng_event_notifier_group *event_notifier_group); + struct lttng_channel *lttng_channel_create(struct lttng_session *session, const char *transport_name, void *buf_addr, diff --git a/src/lttng-abi.c b/src/lttng-abi.c index 3bc2d1fb..00d0a34e 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -59,6 +59,7 @@ static const struct file_operations lttng_proc_ops; #endif static const struct file_operations lttng_session_fops; +static const struct file_operations lttng_event_notifier_group_fops; static const struct file_operations lttng_channel_fops; static const struct file_operations lttng_metadata_fops; static const struct file_operations lttng_event_fops; @@ -105,6 +106,41 @@ fd_error: return ret; } +static +int lttng_abi_create_event_notifier_group(void) +{ + struct lttng_event_notifier_group *event_notifier_group; + struct file *event_notifier_group_file; + int event_notifier_group_fd, ret; + + event_notifier_group = lttng_event_notifier_group_create(); + if (!event_notifier_group) + return -ENOMEM; + + event_notifier_group_fd = lttng_get_unused_fd(); + if (event_notifier_group_fd < 0) { + ret = event_notifier_group_fd; + goto fd_error; + } + event_notifier_group_file = anon_inode_getfile("[lttng_event_notifier_group]", + <tng_event_notifier_group_fops, + event_notifier_group, O_RDWR); + if (IS_ERR(event_notifier_group_file)) { + ret = PTR_ERR(event_notifier_group_file); + goto file_error; + } + + event_notifier_group->file = event_notifier_group_file; + fd_install(event_notifier_group_fd, event_notifier_group_file); + return event_notifier_group_fd; + +file_error: + put_unused_fd(event_notifier_group_fd); +fd_error: + lttng_event_notifier_group_destroy(event_notifier_group); + return ret; +} + static int lttng_abi_tracepoint_list(void) { @@ -306,6 +342,8 @@ long lttng_abi_add_context(struct file *file, * Returns after all previously running probes have completed * LTTNG_KERNEL_TRACER_ABI_VERSION * Returns the LTTng kernel tracer ABI version + * LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_CREATE + * Returns a LTTng event notifier group file descriptor * * The returned session will be deleted when its file descriptor is closed. */ @@ -316,6 +354,8 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case LTTNG_KERNEL_OLD_SESSION: case LTTNG_KERNEL_SESSION: return lttng_abi_create_session(); + case LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_CREATE: + return lttng_abi_create_event_notifier_group(); case LTTNG_KERNEL_OLD_TRACER_VERSION: { struct lttng_kernel_tracer_version v; @@ -1398,6 +1438,37 @@ fd_error: return ret; } +static +long lttng_event_notifier_group_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static +int lttng_event_notifier_group_release(struct inode *inode, struct file *file) +{ + struct lttng_event_notifier_group *event_notifier_group = + file->private_data; + + if (event_notifier_group) + lttng_event_notifier_group_destroy(event_notifier_group); + return 0; +} + +static const struct file_operations lttng_event_notifier_group_fops = { + .owner = THIS_MODULE, + .release = lttng_event_notifier_group_release, + .unlocked_ioctl = lttng_event_notifier_group_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = lttng_event_notifier_group_ioctl, +#endif +}; + /** * lttng_channel_ioctl - lttng syscall through ioctl * diff --git a/src/lttng-events.c b/src/lttng-events.c index e868525d..246c7102 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -48,6 +48,7 @@ #define METADATA_CACHE_DEFAULT_SIZE 4096 static LIST_HEAD(sessions); +static LIST_HEAD(event_notifier_groups); static LIST_HEAD(lttng_transport_list); /* * Protect the sessions and metadata caches. @@ -189,6 +190,64 @@ err: return NULL; } +struct lttng_event_notifier_group *lttng_event_notifier_group_create(void) +{ + struct lttng_transport *transport = NULL; + struct lttng_event_notifier_group *event_notifier_group; + const char *transport_name = "relay-event-notifier"; + size_t subbuf_size = 4096; //TODO + size_t num_subbuf = 16; //TODO + unsigned int switch_timer_interval = 0; + unsigned int read_timer_interval = 0; + + mutex_lock(&sessions_mutex); + + transport = lttng_transport_find(transport_name); + if (!transport) { + printk(KERN_WARNING "LTTng: transport %s not found\n", + transport_name); + goto notransport; + } + if (!try_module_get(transport->owner)) { + printk(KERN_WARNING "LTTng: Can't lock transport %s module.\n", + transport_name); + goto notransport; + } + + event_notifier_group = lttng_kvzalloc(sizeof(struct lttng_event_notifier_group), + GFP_KERNEL); + if (!event_notifier_group) + goto nomem; + + /* + * Initialize the ring buffer used to store event notifier + * notifications. + */ + event_notifier_group->ops = &transport->ops; + event_notifier_group->chan = transport->ops.channel_create( + transport_name, event_notifier_group, NULL, + subbuf_size, num_subbuf, switch_timer_interval, + read_timer_interval); + if (!event_notifier_group->chan) + goto create_error; + + event_notifier_group->transport = transport; + list_add(&event_notifier_group->node, &event_notifier_groups); + + mutex_unlock(&sessions_mutex); + + return event_notifier_group; + +create_error: + lttng_kvfree(event_notifier_group); +nomem: + if (transport) + module_put(transport->owner); +notransport: + mutex_unlock(&sessions_mutex); + return NULL; +} + void metadata_cache_destroy(struct kref *kref) { struct lttng_metadata_cache *cache = @@ -245,6 +304,19 @@ void lttng_session_destroy(struct lttng_session *session) lttng_kvfree(session); } +void lttng_event_notifier_group_destroy(struct lttng_event_notifier_group *event_notifier_group) +{ + if (!event_notifier_group) + return; + + mutex_lock(&sessions_mutex); + event_notifier_group->ops->channel_destroy(event_notifier_group->chan); + module_put(event_notifier_group->transport->owner); + list_del(&event_notifier_group->node); + mutex_unlock(&sessions_mutex); + lttng_kvfree(event_notifier_group); +} + int lttng_session_statedump(struct lttng_session *session) { int ret; -- 2.34.1