X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=lttng-abi.c;h=64ea99da27fc6e126358f223f25972d74bac301f;hb=ff4d1d7e85be94ef43709cd698f0ec9a12f247d1;hp=4df3d673b18c0d84e4d80047fdf096ed52a81350;hpb=d1f652f8d4f6d1de8f6d32ae8711d6469c38892c;p=lttng-modules.git diff --git a/lttng-abi.c b/lttng-abi.c index 4df3d673..64ea99da 100644 --- a/lttng-abi.c +++ b/lttng-abi.c @@ -30,7 +30,7 @@ #include #include #include -#include /* for wrapper_vmalloc_sync_all() */ +#include /* for wrapper_vmalloc_sync_mappings() */ #include #include #include @@ -51,7 +51,13 @@ */ static struct proc_dir_entry *lttng_proc_dentry; -static const struct file_operations lttng_fops; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +static const struct proc_ops lttng_proc_ops; +#else +static const struct file_operations lttng_proc_ops; +#endif + static const struct file_operations lttng_session_fops; static const struct file_operations lttng_channel_fops; static const struct file_operations lttng_metadata_fops; @@ -59,6 +65,7 @@ static const struct file_operations lttng_event_fops; 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); /* * Teardown management: opened file descriptors keep a refcount on the module, @@ -391,13 +398,22 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } } -static const struct file_operations lttng_fops = { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) +static const struct proc_ops lttng_proc_ops = { + .proc_ioctl = lttng_ioctl, +#ifdef CONFIG_COMPAT + .proc_compat_ioctl = lttng_ioctl, +#endif /* CONFIG_COMPAT */ +}; +#else +static const struct file_operations lttng_proc_ops = { .owner = THIS_MODULE, .unlocked_ioctl = lttng_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = lttng_ioctl, -#endif +#endif /* CONFIG_COMPAT */ }; +#endif static int lttng_abi_create_channel(struct file *session_file, @@ -835,6 +851,13 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, int ret; struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; + unsigned int rb_cmd; + bool coherent; + + if (cmd == RING_BUFFER_GET_NEXT_SUBBUF_METADATA_CHECK) + rb_cmd = RING_BUFFER_GET_NEXT_SUBBUF; + else + rb_cmd = cmd; switch (cmd) { case RING_BUFFER_GET_NEXT_SUBBUF: @@ -843,7 +866,7 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, struct lib_ring_buffer *buf = stream->priv; struct channel *chan = buf->backend.chan; - ret = lttng_metadata_output_channel(stream, chan); + ret = lttng_metadata_output_channel(stream, chan, NULL); if (ret > 0) { lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); ret = 0; @@ -869,7 +892,7 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, * Before doing the actual ring buffer flush, write up to one * packet of metadata in the ring buffer. */ - ret = lttng_metadata_output_channel(stream, chan); + ret = lttng_metadata_output_channel(stream, chan, NULL); if (ret < 0) goto err; break; @@ -886,13 +909,28 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, return lttng_metadata_cache_dump(stream); } + case RING_BUFFER_GET_NEXT_SUBBUF_METADATA_CHECK: + { + struct lttng_metadata_stream *stream = filp->private_data; + struct lib_ring_buffer *buf = stream->priv; + struct channel *chan = buf->backend.chan; + + ret = lttng_metadata_output_channel(stream, chan, &coherent); + if (ret > 0) { + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + ret = 0; + } else if (ret < 0) { + goto err; + } + break; + } default: break; } /* PUT_SUBBUF is the one from lib ring buffer, unmodified. */ /* Performing lib ring buffer ioctl after our own. */ - ret = lib_ring_buffer_ioctl(filp, cmd, arg, buf); + ret = lib_ring_buffer_ioctl(filp, rb_cmd, arg, buf); if (ret < 0) goto err; @@ -903,6 +941,10 @@ long lttng_metadata_ring_buffer_ioctl(struct file *filp, cmd, arg); break; } + case RING_BUFFER_GET_NEXT_SUBBUF_METADATA_CHECK: + { + return put_u32(coherent, arg); + } default: break; } @@ -918,6 +960,13 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, int ret; struct lttng_metadata_stream *stream = filp->private_data; struct lib_ring_buffer *buf = stream->priv; + unsigned int rb_cmd; + bool coherent; + + if (cmd == RING_BUFFER_GET_NEXT_SUBBUF_METADATA_CHECK) + rb_cmd = RING_BUFFER_GET_NEXT_SUBBUF; + else + rb_cmd = cmd; switch (cmd) { case RING_BUFFER_GET_NEXT_SUBBUF: @@ -926,7 +975,7 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, struct lib_ring_buffer *buf = stream->priv; struct channel *chan = buf->backend.chan; - ret = lttng_metadata_output_channel(stream, chan); + ret = lttng_metadata_output_channel(stream, chan, NULL); if (ret > 0) { lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); ret = 0; @@ -952,7 +1001,7 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, * Before doing the actual ring buffer flush, write up to one * packet of metadata in the ring buffer. */ - ret = lttng_metadata_output_channel(stream, chan); + ret = lttng_metadata_output_channel(stream, chan, NULL); if (ret < 0) goto err; break; @@ -969,13 +1018,28 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, return lttng_metadata_cache_dump(stream); } + case RING_BUFFER_GET_NEXT_SUBBUF_METADATA_CHECK: + { + struct lttng_metadata_stream *stream = filp->private_data; + struct lib_ring_buffer *buf = stream->priv; + struct channel *chan = buf->backend.chan; + + ret = lttng_metadata_output_channel(stream, chan, &coherent); + if (ret > 0) { + lib_ring_buffer_switch_slow(buf, SWITCH_ACTIVE); + ret = 0; + } else if (ret < 0) { + goto err; + } + break; + } default: break; } /* PUT_SUBBUF is the one from lib ring buffer, unmodified. */ /* Performing lib ring buffer ioctl after our own. */ - ret = lib_ring_buffer_compat_ioctl(filp, cmd, arg, buf); + ret = lib_ring_buffer_compat_ioctl(filp, rb_cmd, arg, buf); if (ret < 0) goto err; @@ -986,6 +1050,10 @@ long lttng_metadata_ring_buffer_compat_ioctl(struct file *filp, cmd, arg); break; } + case RING_BUFFER_GET_NEXT_SUBBUF_METADATA_CHECK: + { + return put_u32(coherent, arg); + } default: break; } @@ -1022,8 +1090,12 @@ int lttng_metadata_ring_buffer_release(struct inode *inode, struct file *file) struct lttng_metadata_stream *stream = file->private_data; struct lib_ring_buffer *buf = stream->priv; + mutex_lock(&stream->metadata_cache->lock); + list_del(&stream->list); + mutex_unlock(&stream->metadata_cache->lock); kref_put(&stream->metadata_cache->refcount, metadata_cache_destroy); module_put(stream->transport->owner); + kfree(stream); return lib_ring_buffer_release(inode, file, buf); } @@ -1152,6 +1224,8 @@ int lttng_abi_open_metadata_stream(struct file *channel_file) metadata_stream->priv = buf; stream_priv = metadata_stream; metadata_stream->transport = channel->transport; + /* Initial state is an empty metadata, considered as incoherent. */ + metadata_stream->coherent = false; /* * Since life-time of metadata cache differs from that of @@ -1173,8 +1247,10 @@ int lttng_abi_open_metadata_stream(struct file *channel_file) if (ret < 0) goto fd_error; + mutex_lock(&session->metadata_cache->lock); list_add(&metadata_stream->list, &session->metadata_cache->metadata_stream); + mutex_unlock(&session->metadata_cache->lock); return ret; fd_error: @@ -1206,7 +1282,8 @@ int lttng_abi_create_event(struct file *channel_file, event_param->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; break; case LTTNG_KERNEL_FUNCTION: - event_param->u.ftrace.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; + WARN_ON_ONCE(1); + /* Not implemented. */ break; default: break; @@ -1357,9 +1434,8 @@ long lttng_channel_ioctl(struct file *file, unsigned int cmd, unsigned long arg) sizeof(uevent_param->u.kretprobe.symbol_name)); break; case LTTNG_KERNEL_FUNCTION: - memcpy(uevent_param->u.ftrace.symbol_name, - old_uevent_param->u.ftrace.symbol_name, - sizeof(uevent_param->u.ftrace.symbol_name)); + WARN_ON_ONCE(1); + /* Not implemented. */ break; default: break; @@ -1688,6 +1764,11 @@ static int put_u64(uint64_t val, unsigned long arg) return put_user(val, (uint64_t __user *) arg); } +static int put_u32(uint32_t val, unsigned long arg) +{ + return put_user(val, (uint32_t __user *) arg); +} + static long lttng_stream_ring_buffer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -1923,7 +2004,7 @@ int __init lttng_abi_init(void) { int ret = 0; - wrapper_vmalloc_sync_all(); + wrapper_vmalloc_sync_mappings(); lttng_clock_ref(); ret = lttng_tp_mempool_init(); @@ -1932,7 +2013,7 @@ int __init lttng_abi_init(void) } lttng_proc_dentry = proc_create_data("lttng", S_IRUSR | S_IWUSR, NULL, - <tng_fops, NULL); + <tng_proc_ops, NULL); if (!lttng_proc_dentry) { printk(KERN_ERR "Error creating LTTng control file\n");