}
int trace_probe_init(struct trace_probe *tp, const char *event,
- const char *group, size_t event_data_size)
+ const char *group, bool alloc_filter)
{
struct trace_event_call *call;
+ size_t size = sizeof(struct trace_probe_event);
int ret = 0;
if (!event || !group)
return -EINVAL;
- tp->event = kzalloc(sizeof(struct trace_probe_event) + event_data_size,
- GFP_KERNEL);
+ if (alloc_filter)
+ size += sizeof(struct trace_uprobe_filter);
+
+ tp->event = kzalloc(size, GFP_KERNEL);
if (!tp->event)
return -ENOMEM;
const struct fetch_type *type; /* Type of this argument */
};
+struct trace_uprobe_filter {
+ rwlock_t rwlock;
+ int nr_systemwide;
+ struct list_head perf_events;
+};
+
/* Event call and class holder */
struct trace_probe_event {
unsigned int flags; /* For TP_FLAG_* */
struct trace_event_call call;
struct list_head files;
struct list_head probes;
- char data[0];
+ struct trace_uprobe_filter filter[0];
};
struct trace_probe {
}
int trace_probe_init(struct trace_probe *tp, const char *event,
- const char *group, size_t event_data_size);
+ const char *group, bool alloc_filter);
void trace_probe_cleanup(struct trace_probe *tp);
int trace_probe_append(struct trace_probe *tp, struct trace_probe *to);
void trace_probe_unlink(struct trace_probe *tp);
#define DATAOF_TRACE_ENTRY(entry, is_return) \
((void*)(entry) + SIZEOF_TRACE_ENTRY(is_return))
-struct trace_uprobe_filter {
- rwlock_t rwlock;
- int nr_systemwide;
- struct list_head perf_events;
-};
-
static int trace_uprobe_create(int argc, const char **argv);
static int trace_uprobe_show(struct seq_file *m, struct dyn_event *ev);
static int trace_uprobe_release(struct dyn_event *ev);
}
NOKPROBE_SYMBOL(process_fetch_insn)
-static struct trace_uprobe_filter *
-trace_uprobe_get_filter(struct trace_uprobe *tu)
-{
- struct trace_probe_event *event = tu->tp.event;
-
- return (struct trace_uprobe_filter *)&event->data[0];
-}
-
static inline void init_trace_uprobe_filter(struct trace_uprobe_filter *filter)
{
rwlock_init(&filter->rwlock);
if (!tu)
return ERR_PTR(-ENOMEM);
- ret = trace_probe_init(&tu->tp, event, group,
- sizeof(struct trace_uprobe_filter));
+ ret = trace_probe_init(&tu->tp, event, group, true);
if (ret < 0)
goto error;
tu->consumer.handler = uprobe_dispatcher;
if (is_ret)
tu->consumer.ret_handler = uretprobe_dispatcher;
- init_trace_uprobe_filter(trace_uprobe_get_filter(tu));
+ init_trace_uprobe_filter(tu->tp.event->filter);
return tu;
error:
struct trace_uprobe *tu;
tu = container_of(tp, struct trace_uprobe, tp);
- WARN_ON(!uprobe_filter_is_empty(trace_uprobe_get_filter(tu)));
+ WARN_ON(!uprobe_filter_is_empty(tu->tp.event->filter));
list_for_each_entry(pos, trace_probe_probe_list(tp), list) {
tu = container_of(pos, struct trace_uprobe, tp);
}
tu = container_of(tp, struct trace_uprobe, tp);
- WARN_ON(!uprobe_filter_is_empty(trace_uprobe_get_filter(tu)));
+ WARN_ON(!uprobe_filter_is_empty(tu->tp.event->filter));
if (enabled)
return 0;
return -ENODEV;
tu = container_of(tp, struct trace_uprobe, tp);
- if (trace_uprobe_filter_remove(trace_uprobe_get_filter(tu), event))
+ if (trace_uprobe_filter_remove(tu->tp.event->filter, event))
return 0;
list_for_each_entry(pos, trace_probe_probe_list(tp), list) {
return -ENODEV;
tu = container_of(tp, struct trace_uprobe, tp);
- if (trace_uprobe_filter_add(trace_uprobe_get_filter(tu), event))
+ if (trace_uprobe_filter_add(tu->tp.event->filter, event))
return 0;
list_for_each_entry(pos, trace_probe_probe_list(tp), list) {
int ret;
tu = container_of(uc, struct trace_uprobe, consumer);
- filter = trace_uprobe_get_filter(tu);
+ filter = tu->tp.event->filter;
read_lock(&filter->rwlock);
ret = __uprobe_perf_filter(filter, mm);