Implement event notifier kretprobe support
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 28 Feb 2022 20:20:51 +0000 (15:20 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 15 Jul 2024 20:58:48 +0000 (16:58 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I32b42ddad79889a19ee8833ed9b52e4a37505f7b

src/lttng-abi.c
src/lttng-events.c
src/lttng-kretprobes.c

index 66c4a311cd03d67c44e7521bf2ac1551d0e94036..1d074b291081cf399952bbc771d3b758e5773b3d 100644 (file)
@@ -2386,27 +2386,6 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file,
        struct file *event_notifier_file;
        void *priv;
 
-       switch (event_notifier_param->event.instrumentation) {
-       case LTTNG_KERNEL_ABI_TRACEPOINT:
-               lttng_fallthrough;
-       case LTTNG_KERNEL_ABI_UPROBE:
-               break;
-       case LTTNG_KERNEL_ABI_KPROBE:
-               event_notifier_param->event.u.kprobe.symbol_name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
-               break;
-       case LTTNG_KERNEL_ABI_SYSCALL:
-               break;
-       case LTTNG_KERNEL_ABI_KRETPROBE:
-               /* Placing an event notifier on kretprobe is not supported. */
-               lttng_fallthrough;
-       case LTTNG_KERNEL_ABI_FUNCTION:
-               lttng_fallthrough;
-       case LTTNG_KERNEL_ABI_NOOP:
-       default:
-               ret = -EINVAL;
-               goto inval_instr;
-       }
-
        switch (event_notifier_param->event.instrumentation) {
        case LTTNG_KERNEL_ABI_TRACEPOINT:
                lttng_fallthrough;
@@ -2431,6 +2410,16 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file,
        }
 
        event_notifier_param->event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
+       switch (event_notifier_param->event.instrumentation) {
+       case LTTNG_KERNEL_ABI_KRETPROBE:
+               event_notifier_param->event.u.kretprobe.symbol_name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
+               break;
+       case LTTNG_KERNEL_ABI_KPROBE:
+               event_notifier_param->event.u.kprobe.symbol_name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
+               break;
+       default:
+               break;
+       }
 
        event_notifier_fd = get_unused_fd_flags(0);
        if (event_notifier_fd < 0) {
@@ -2485,8 +2474,6 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file,
 
        case LTTNG_KERNEL_ABI_KPROBE:
                lttng_fallthrough;
-       case LTTNG_KERNEL_ABI_KRETPROBE:
-               lttng_fallthrough;
        case LTTNG_KERNEL_ABI_UPROBE:
        {
                struct lttng_kernel_event_common *event;
@@ -2508,6 +2495,48 @@ int lttng_abi_create_event_notifier(struct file *event_notifier_group_file,
                break;
        }
 
+       case LTTNG_KERNEL_ABI_KRETPROBE:
+       {
+               struct lttng_kernel_event_common *event[2];
+               struct lttng_event_notifier_enabler *event_enabler;
+               struct lttng_kernel_event_pair event_pair;
+
+               if (strlen(event_notifier_param->event.name) + strlen("_entry") >= LTTNG_KERNEL_ABI_SYM_NAME_LEN)
+                       return -EINVAL;
+
+               memset(&event_pair, 0, sizeof(event_pair));
+               event_enabler = lttng_event_notifier_enabler_create(LTTNG_ENABLER_FORMAT_NAME,
+                               event_notifier_param, event_notifier_group);
+               if (!event_enabler) {
+                       ret = -ENOMEM;
+                       goto event_notifier_error;
+               }
+
+               strcpy(event_pair.name, event_notifier_param->event.name);
+               strcat(event_pair.name, "_entry");
+               /*
+                * We tolerate no failure path after event creation. It
+                * will stay invariant for the rest of the session.
+                */
+               event[0] = lttng_kernel_event_create(&event_enabler->parent, NULL, &event_pair);
+               if (IS_ERR(event[0])) {
+                       lttng_event_enabler_destroy(&event_enabler->parent);
+                       ret = PTR_ERR(event[0]);
+                       goto event_notifier_error;
+               }
+
+               strcpy(event_pair.name, event_notifier_param->event.name);
+               strcat(event_pair.name, "_exit");
+               event[1] = lttng_kernel_event_create(&event_enabler->parent, NULL, &event_pair);
+               lttng_event_enabler_destroy(&event_enabler->parent);
+               if (IS_ERR(event[1])) {
+                       ret = PTR_ERR(event[1]);
+                       goto event_notifier_error;
+               }
+               priv = event[0];
+               break;
+       }
+
        case LTTNG_KERNEL_ABI_FUNCTION:
                lttng_fallthrough;
        case LTTNG_KERNEL_ABI_NOOP:
index 97c123b2c4d04ec6b9ffaf8b7dfaac099e7d1395..860d8f7e0829a7addcdf2686bb3297a0c932bafd 100644 (file)
@@ -673,14 +673,7 @@ int lttng_event_enable(struct lttng_kernel_event_common *event)
                break;
        }
        case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
-               switch (event->priv->instrumentation) {
-               case LTTNG_KERNEL_ABI_KRETPROBE:
-                       ret = -EINVAL;
-                       goto end;
-               default:
-                       break;
-               }
-               break;
+               lttng_fallthrough;
        case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
                break;
        default:
@@ -739,14 +732,7 @@ int lttng_event_disable(struct lttng_kernel_event_common *event)
                break;
        }
        case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
-               switch (event->priv->instrumentation) {
-               case LTTNG_KERNEL_ABI_KRETPROBE:
-                       ret = -EINVAL;
-                       goto end;
-               default:
-                       break;
-               }
-               break;
+               lttng_fallthrough;
        case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
                break;
        default:
@@ -1767,11 +1753,11 @@ void unregister_event(struct lttng_kernel_event_common *event)
                case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
                        lttng_fallthrough;
                case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
+                       lttng_fallthrough;
+               case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
                        lttng_kretprobes_unregister(event);
                        ret = 0;
                        break;
-               case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
-                       WARN_ON_ONCE(1);
                        break;
                }
                break;
index 1b8bbb0acacf8319d6b5e984fb7341aff1263be1..d59bd0de629565b12b777b000cc3625767878607 100644 (file)
@@ -104,6 +104,16 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi,
                chan->ops->event_commit(&ctx);
                break;
        }
+       case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
+       {
+               struct lttng_kernel_event_notifier *event_notifier =
+                       container_of(event, struct lttng_kernel_event_notifier, parent);
+               struct lttng_kernel_notification_ctx notif_ctx;
+
+               notif_ctx.eval_capture = LTTNG_READ_ONCE(event_notifier->eval_capture);
+               event_notifier->notification_send(event_notifier, NULL, NULL, &notif_ctx);
+               break;
+       }
        case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
        {
                struct lttng_kernel_event_counter *event_counter =
@@ -112,8 +122,6 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi,
                (void) event_counter->chan->ops->event_counter_add(event_counter, 1);
                break;
        }
-       case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
-               lttng_fallthrough;
        default:
                WARN_ON_ONCE(1);
        }
This page took 0.030206 seconds and 4 git commands to generate.