From 83b802dc7f83a776bc9aea34562ab591ba7a65ee Mon Sep 17 00:00:00 2001 From: Francis Deslauriers Date: Tue, 21 Jan 2020 18:45:11 -0500 Subject: [PATCH] Namespace uprobe functions relating to events Signed-off-by: Francis Deslauriers Signed-off-by: Mathieu Desnoyers Change-Id: I4130b5e9fe88ee5121646a3303b262266db658be --- include/lttng/events.h | 30 +++++++++------- src/lttng-events.c | 8 ++--- src/probes/lttng-uprobes.c | 72 +++++++++++++++++++++++++------------- 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/include/lttng/events.h b/include/lttng/events.h index cf04a305..ff0a48ff 100644 --- a/include/lttng/events.h +++ b/include/lttng/events.h @@ -270,7 +270,9 @@ struct lttng_enabler_ref { }; struct lttng_uprobe_handler { - struct lttng_event *event; + union { + struct lttng_event *event; + } u; loff_t offset; struct uprobe_consumer up_consumer; struct list_head node; @@ -281,6 +283,11 @@ struct lttng_kprobe { char *symbol_name; }; +struct lttng_uprobe { + struct inode *inode; + struct list_head head; +}; + enum lttng_syscall_entryexit { LTTNG_SYSCALL_ENTRY, LTTNG_SYSCALL_EXIT, @@ -310,10 +317,7 @@ struct lttng_event { struct lttng_krp *lttng_krp; char *symbol_name; } kretprobe; - struct { - struct inode *inode; - struct list_head head; - } uprobe; + struct lttng_uprobe uprobe; struct { char *syscall_name; enum lttng_syscall_entryexit entryexit; @@ -1071,34 +1075,34 @@ int lttng_event_add_callsite(struct lttng_event *event, struct lttng_kernel_event_callsite *callsite); #ifdef CONFIG_UPROBES -int lttng_uprobes_register(const char *name, +int lttng_uprobes_register_event(const char *name, int fd, struct lttng_event *event); -int lttng_uprobes_add_callsite(struct lttng_event *event, +int lttng_uprobes_event_add_callsite(struct lttng_event *event, struct lttng_kernel_event_callsite *callsite); -void lttng_uprobes_unregister(struct lttng_event *event); -void lttng_uprobes_destroy_private(struct lttng_event *event); +void lttng_uprobes_unregister_event(struct lttng_event *event); +void lttng_uprobes_destroy_event_private(struct lttng_event *event); #else static inline -int lttng_uprobes_register(const char *name, +int lttng_uprobes_register_event(const char *name, int fd, struct lttng_event *event) { return -ENOSYS; } static inline -int lttng_uprobes_add_callsite(struct lttng_event *event, +int lttng_uprobes_event_add_callsite(struct lttng_event *event, struct lttng_kernel_event_callsite *callsite) { return -ENOSYS; } static inline -void lttng_uprobes_unregister(struct lttng_event *event) +void lttng_uprobes_unregister_event(struct lttng_event *event) { } static inline -void lttng_uprobes_destroy_private(struct lttng_event *event) +void lttng_uprobes_destroy_event_private(struct lttng_event *event) { } #endif diff --git a/src/lttng-events.c b/src/lttng-events.c index 84ffd283..0e11c5d8 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -958,7 +958,7 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, */ smp_wmb(); - ret = lttng_uprobes_register(event_param->name, + ret = lttng_uprobes_register_event(event_param->name, event_param->u.uprobe.fd, event); if (ret) @@ -1206,7 +1206,7 @@ int _lttng_event_unregister(struct lttng_event *event) ret = 0; break; case LTTNG_KERNEL_UPROBE: - lttng_uprobes_unregister(event); + lttng_uprobes_unregister_event(event); ret = 0; break; case LTTNG_KERNEL_FUNCTION: /* Fall-through */ @@ -1307,7 +1307,7 @@ void _lttng_event_destroy(struct lttng_event *event) break; case LTTNG_KERNEL_UPROBE: module_put(event->desc->owner); - lttng_uprobes_destroy_private(event); + lttng_uprobes_destroy_event_private(event); break; case LTTNG_KERNEL_FUNCTION: /* Fall-through */ default: @@ -2163,7 +2163,7 @@ int lttng_event_add_callsite(struct lttng_event *event, switch (event->instrumentation) { case LTTNG_KERNEL_UPROBE: - return lttng_uprobes_add_callsite(event, callsite); + return lttng_uprobes_event_add_callsite(event, callsite); default: return -EINVAL; } diff --git a/src/probes/lttng-uprobes.c b/src/probes/lttng-uprobes.c index 435ff5ac..d2365320 100644 --- a/src/probes/lttng-uprobes.c +++ b/src/probes/lttng-uprobes.c @@ -23,11 +23,11 @@ #include static -int lttng_uprobes_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs) +int lttng_uprobes_event_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs) { struct lttng_uprobe_handler *uprobe_handler = container_of(uc, struct lttng_uprobe_handler, up_consumer); - struct lttng_event *event = uprobe_handler->event; + struct lttng_event *event = uprobe_handler->u.event; struct lttng_probe_ctx lttng_probe_ctx = { .event = event, .interruptible = !lttng_regs_irqs_disabled(regs), @@ -142,13 +142,17 @@ error: return inode; } -int lttng_uprobes_add_callsite(struct lttng_event *event, - struct lttng_kernel_event_callsite __user *callsite) + +static +int lttng_uprobes_add_callsite(struct lttng_uprobe *uprobe, + struct lttng_kernel_event_callsite __user *callsite, + int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs), + void *priv_data) { int ret = 0; struct lttng_uprobe_handler *uprobe_handler; - if (!event) { + if (!priv_data) { ret = -EINVAL; goto end; } @@ -163,25 +167,25 @@ int lttng_uprobes_add_callsite(struct lttng_event *event, /* Ensure the memory we just allocated don't trigger page faults. */ wrapper_vmalloc_sync_mappings(); - uprobe_handler->event = event; - uprobe_handler->up_consumer.handler = lttng_uprobes_handler_pre; + uprobe_handler->u.event = priv_data; + uprobe_handler->up_consumer.handler = handler; ret = copy_from_user(&uprobe_handler->offset, &callsite->u.uprobe.offset, sizeof(uint64_t)); if (ret) { goto register_error; } - ret = wrapper_uprobe_register(event->u.uprobe.inode, + ret = wrapper_uprobe_register(uprobe->inode, uprobe_handler->offset, &uprobe_handler->up_consumer); if (ret) { printk(KERN_WARNING "LTTng: Error registering probe on inode %lu " - "and offset 0x%llx\n", event->u.uprobe.inode->i_ino, + "and offset 0x%llx\n", uprobe->inode->i_ino, uprobe_handler->offset); ret = -1; goto register_error; } - list_add(&uprobe_handler->node, &event->u.uprobe.head); + list_add(&uprobe_handler->node, &uprobe->head); return ret; @@ -190,37 +194,57 @@ register_error: end: return ret; } -EXPORT_SYMBOL_GPL(lttng_uprobes_add_callsite); -int lttng_uprobes_register(const char *name, int fd, struct lttng_event *event) +int lttng_uprobes_event_add_callsite(struct lttng_event *event, + struct lttng_kernel_event_callsite __user *callsite) +{ + return lttng_uprobes_add_callsite(&event->u.uprobe, callsite, + lttng_uprobes_event_handler_pre, event); +} +EXPORT_SYMBOL_GPL(lttng_uprobes_event_add_callsite); + +static +int lttng_uprobes_register(struct lttng_uprobe *uprobe, int fd) { int ret = 0; struct inode *inode; - ret = lttng_create_uprobe_event(name, event); - if (ret) - goto error; - inode = get_inode_from_fd(fd); if (!inode) { printk(KERN_WARNING "LTTng: Cannot get inode from fd\n"); ret = -EBADF; goto inode_error; } - event->u.uprobe.inode = inode; - INIT_LIST_HEAD(&event->u.uprobe.head); + uprobe->inode = inode; + INIT_LIST_HEAD(&uprobe->head); + +inode_error: + return ret; +} + +int lttng_uprobes_register_event(const char *name, int fd, struct lttng_event *event) +{ + int ret = 0; + + ret = lttng_create_uprobe_event(name, event); + if (ret) + goto error; + + ret = lttng_uprobes_register(&event->u.uprobe, fd); + if (ret) + goto register_error; return 0; -inode_error: +register_error: kfree(event->desc->name); kfree(event->desc); error: return ret; } -EXPORT_SYMBOL_GPL(lttng_uprobes_register); +EXPORT_SYMBOL_GPL(lttng_uprobes_register_event); -void lttng_uprobes_unregister(struct lttng_event *event) +void lttng_uprobes_unregister_event(struct lttng_event *event) { struct lttng_uprobe_handler *iter, *tmp; @@ -235,15 +259,15 @@ void lttng_uprobes_unregister(struct lttng_event *event) kfree(iter); } } -EXPORT_SYMBOL_GPL(lttng_uprobes_unregister); +EXPORT_SYMBOL_GPL(lttng_uprobes_unregister_event); -void lttng_uprobes_destroy_private(struct lttng_event *event) +void lttng_uprobes_destroy_event_private(struct lttng_event *event) { iput(event->u.uprobe.inode); kfree(event->desc->name); kfree(event->desc); } -EXPORT_SYMBOL_GPL(lttng_uprobes_destroy_private); +EXPORT_SYMBOL_GPL(lttng_uprobes_destroy_event_private); MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Yannick Brosseau"); -- 2.34.1