summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
c74b9c6)
The session daemon expects that all events (enablers and events) are
disabled when created, so we can attach a filter before enabling them.
Also fix the kretprobe to ensure we can enable/disable both the entry
and return probe (--function instrumentation).
Fixes: #926
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
ret = -EEXIST;
goto end;
}
ret = -EEXIST;
goto end;
}
- ACCESS_ONCE(event->enabled) = 1;
- lttng_session_sync_enablers(event->chan->session);
+ switch (event->instrumentation) {
+ case LTTNG_KERNEL_TRACEPOINT:
+ case LTTNG_KERNEL_SYSCALL:
+ ret = -EINVAL;
+ break;
+ case LTTNG_KERNEL_KPROBE:
+ case LTTNG_KERNEL_FUNCTION:
+ case LTTNG_KERNEL_NOOP:
+ ACCESS_ONCE(event->enabled) = 1;
+ break;
+ case LTTNG_KERNEL_KRETPROBE:
+ ret = lttng_kretprobes_event_enable_state(event, 1);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ ret = -EINVAL;
+ }
end:
mutex_unlock(&sessions_mutex);
return ret;
end:
mutex_unlock(&sessions_mutex);
return ret;
ret = -EEXIST;
goto end;
}
ret = -EEXIST;
goto end;
}
- ACCESS_ONCE(event->enabled) = 0;
- lttng_session_sync_enablers(event->chan->session);
+ switch (event->instrumentation) {
+ case LTTNG_KERNEL_TRACEPOINT:
+ case LTTNG_KERNEL_SYSCALL:
+ ret = -EINVAL;
+ break;
+ case LTTNG_KERNEL_KPROBE:
+ case LTTNG_KERNEL_FUNCTION:
+ case LTTNG_KERNEL_NOOP:
+ ACCESS_ONCE(event->enabled) = 0;
+ break;
+ case LTTNG_KERNEL_KRETPROBE:
+ ret = lttng_kretprobes_event_enable_state(event, 0);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ ret = -EINVAL;
+ }
end:
mutex_unlock(&sessions_mutex);
return ret;
end:
mutex_unlock(&sessions_mutex);
return ret;
smp_wmb();
break;
case LTTNG_KERNEL_KPROBE:
smp_wmb();
break;
case LTTNG_KERNEL_KPROBE:
+ /*
+ * Needs to be explicitly enabled after creation, since
+ * we may want to apply filters.
+ */
+ event->enabled = 0;
event->registered = 1;
/*
* Populate lttng_event structure before event
event->registered = 1;
/*
* Populate lttng_event structure before event
struct lttng_event *event_return;
/* kretprobe defines 2 events */
struct lttng_event *event_return;
/* kretprobe defines 2 events */
+ /*
+ * Needs to be explicitly enabled after creation, since
+ * we may want to apply filters.
+ */
+ event->enabled = 0;
event->registered = 1;
event_return =
kmem_cache_zalloc(event_cache, GFP_KERNEL);
event->registered = 1;
event_return =
kmem_cache_zalloc(event_cache, GFP_KERNEL);
event_return->chan = chan;
event_return->filter = filter;
event_return->id = chan->free_event_id++;
event_return->chan = chan;
event_return->filter = filter;
event_return->id = chan->free_event_id++;
- event_return->enabled = 1;
+ event_return->enabled = 0;
event_return->registered = 1;
event_return->instrumentation = itype;
/*
event_return->registered = 1;
event_return->instrumentation = itype;
/*
break;
}
case LTTNG_KERNEL_FUNCTION:
break;
}
case LTTNG_KERNEL_FUNCTION:
+ /*
+ * Needs to be explicitly enabled after creation, since
+ * we may want to apply filters.
+ */
+ event->enabled = 0;
event->registered = 1;
/*
* Populate lttng_event structure before event
event->registered = 1;
/*
* Populate lttng_event structure before event
break;
case LTTNG_KERNEL_NOOP:
case LTTNG_KERNEL_SYSCALL:
break;
case LTTNG_KERNEL_NOOP:
case LTTNG_KERNEL_SYSCALL:
+ /*
+ * Needs to be explicitly enabled after creation, since
+ * we may want to apply filters.
+ */
+ event->enabled = 0;
event->registered = 0;
event->desc = event_desc;
if (!event->desc) {
event->registered = 0;
event->desc = event_desc;
if (!event->desc) {
struct lttng_event *event_exit);
void lttng_kretprobes_unregister(struct lttng_event *event);
void lttng_kretprobes_destroy_private(struct lttng_event *event);
struct lttng_event *event_exit);
void lttng_kretprobes_unregister(struct lttng_event *event);
void lttng_kretprobes_destroy_private(struct lttng_event *event);
+int lttng_kretprobes_event_enable_state(struct lttng_event *event,
+ int enable);
#else
static inline
int lttng_kretprobes_register(const char *name,
#else
static inline
int lttng_kretprobes_register(const char *name,
void lttng_kretprobes_destroy_private(struct lttng_event *event)
{
}
void lttng_kretprobes_destroy_private(struct lttng_event *event)
{
}
+
+static inline
+int lttng_kretprobes_event_enable_state(struct lttng_event *event,
+ int enable)
+{
+ return -ENOSYS;
+}
#endif
#ifdef CONFIG_DYNAMIC_FTRACE
#endif
#ifdef CONFIG_DYNAMIC_FTRACE
}
EXPORT_SYMBOL_GPL(lttng_kretprobes_destroy_private);
}
EXPORT_SYMBOL_GPL(lttng_kretprobes_destroy_private);
+int lttng_kretprobes_event_enable_state(struct lttng_event *event,
+ int enable)
+{
+ struct lttng_event *event_return;
+ struct lttng_krp *lttng_krp;
+
+ if (event->instrumentation != LTTNG_KERNEL_KRETPROBE) {
+ return -EINVAL;
+ }
+ if (event->enabled == enable) {
+ return -EBUSY;
+ }
+ lttng_krp = event->u.kretprobe.lttng_krp;
+ event_return = lttng_krp->event[EVENT_RETURN];
+ ACCESS_ONCE(event->enabled) = enable;
+ ACCESS_ONCE(event_return->enabled) = enable;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_kretprobes_event_enable_state);
+
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Mathieu Desnoyers");
MODULE_DESCRIPTION("Linux Trace Toolkit Kretprobes Support");
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Mathieu Desnoyers");
MODULE_DESCRIPTION("Linux Trace Toolkit Kretprobes Support");