git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
tracing/uprobes: Fail to unregister if probe event files are in use
[pandora-kernel.git]
/
kernel
/
trace
/
trace_uprobe.c
diff --git
a/kernel/trace/trace_uprobe.c
b/kernel/trace/trace_uprobe.c
index
d5d0cd3
..
272261b
100644
(file)
--- a/
kernel/trace/trace_uprobe.c
+++ b/
kernel/trace/trace_uprobe.c
@@
-70,7
+70,7
@@
struct trace_uprobe {
(sizeof(struct probe_arg) * (n)))
static int register_uprobe_event(struct trace_uprobe *tu);
(sizeof(struct probe_arg) * (n)))
static int register_uprobe_event(struct trace_uprobe *tu);
-static
void
unregister_uprobe_event(struct trace_uprobe *tu);
+static
int
unregister_uprobe_event(struct trace_uprobe *tu);
static DEFINE_MUTEX(uprobe_lock);
static LIST_HEAD(uprobe_list);
static DEFINE_MUTEX(uprobe_lock);
static LIST_HEAD(uprobe_list);
@@
-164,11
+164,17
@@
static struct trace_uprobe *find_probe_event(const char *event, const char *grou
}
/* Unregister a trace_uprobe and probe_event: call with locking uprobe_lock */
}
/* Unregister a trace_uprobe and probe_event: call with locking uprobe_lock */
-static
void
unregister_trace_uprobe(struct trace_uprobe *tu)
+static
int
unregister_trace_uprobe(struct trace_uprobe *tu)
{
{
+ int ret;
+
+ ret = unregister_uprobe_event(tu);
+ if (ret)
+ return ret;
+
list_del(&tu->list);
list_del(&tu->list);
- unregister_uprobe_event(tu);
free_trace_uprobe(tu);
free_trace_uprobe(tu);
+ return 0;
}
/* Register a trace_uprobe and probe_event */
}
/* Register a trace_uprobe and probe_event */
@@
-181,9
+187,12
@@
static int register_trace_uprobe(struct trace_uprobe *tu)
/* register as an event */
old_tp = find_probe_event(tu->call.name, tu->call.class->system);
/* register as an event */
old_tp = find_probe_event(tu->call.name, tu->call.class->system);
- if (old_tp)
+ if (old_tp)
{
/* delete old event */
/* delete old event */
- unregister_trace_uprobe(old_tp);
+ ret = unregister_trace_uprobe(old_tp);
+ if (ret)
+ goto end;
+ }
ret = register_uprobe_event(tu);
if (ret) {
ret = register_uprobe_event(tu);
if (ret) {
@@
-256,6
+265,8
@@
static int create_trace_uprobe(int argc, char **argv)
group = UPROBE_EVENT_SYSTEM;
if (is_delete) {
group = UPROBE_EVENT_SYSTEM;
if (is_delete) {
+ int ret;
+
if (!event) {
pr_info("Delete command needs an event name.\n");
return -EINVAL;
if (!event) {
pr_info("Delete command needs an event name.\n");
return -EINVAL;
@@
-269,9
+280,9
@@
static int create_trace_uprobe(int argc, char **argv)
return -ENOENT;
}
/* delete an event */
return -ENOENT;
}
/* delete an event */
- unregister_trace_uprobe(tu);
+
ret =
unregister_trace_uprobe(tu);
mutex_unlock(&uprobe_lock);
mutex_unlock(&uprobe_lock);
- return
0
;
+ return
ret
;
}
if (argc < 2) {
}
if (argc < 2) {
@@
-408,16
+419,20
@@
fail_address_parse:
return ret;
}
return ret;
}
-static
void
cleanup_all_probes(void)
+static
int
cleanup_all_probes(void)
{
struct trace_uprobe *tu;
{
struct trace_uprobe *tu;
+ int ret = 0;
mutex_lock(&uprobe_lock);
while (!list_empty(&uprobe_list)) {
tu = list_entry(uprobe_list.next, struct trace_uprobe, list);
mutex_lock(&uprobe_lock);
while (!list_empty(&uprobe_list)) {
tu = list_entry(uprobe_list.next, struct trace_uprobe, list);
- unregister_trace_uprobe(tu);
+ ret = unregister_trace_uprobe(tu);
+ if (ret)
+ break;
}
mutex_unlock(&uprobe_lock);
}
mutex_unlock(&uprobe_lock);
+ return ret;
}
/* Probes listing interfaces */
}
/* Probes listing interfaces */
@@
-462,8
+477,13
@@
static const struct seq_operations probes_seq_op = {
static int probes_open(struct inode *inode, struct file *file)
{
static int probes_open(struct inode *inode, struct file *file)
{
- if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC))
- cleanup_all_probes();
+ int ret;
+
+ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
+ ret = cleanup_all_probes();
+ if (ret)
+ return ret;
+ }
return seq_open(file, &probes_seq_op);
}
return seq_open(file, &probes_seq_op);
}
@@
-818,8
+838,6
@@
static void uprobe_perf_print(struct trace_uprobe *tu,
size = SIZEOF_TRACE_ENTRY(is_ret_probe(tu));
size = ALIGN(size + tu->size + sizeof(u32), sizeof(u64)) - sizeof(u32);
size = SIZEOF_TRACE_ENTRY(is_ret_probe(tu));
size = ALIGN(size + tu->size + sizeof(u32), sizeof(u64)) - sizeof(u32);
- if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, "profile buffer not large enough"))
- return;
preempt_disable();
head = this_cpu_ptr(call->perf_events);
preempt_disable();
head = this_cpu_ptr(call->perf_events);
@@
-970,12
+988,17
@@
static int register_uprobe_event(struct trace_uprobe *tu)
return ret;
}
return ret;
}
-static
void
unregister_uprobe_event(struct trace_uprobe *tu)
+static
int
unregister_uprobe_event(struct trace_uprobe *tu)
{
{
+ int ret;
+
/* tu->event is unregistered in trace_remove_event_call() */
/* tu->event is unregistered in trace_remove_event_call() */
- trace_remove_event_call(&tu->call);
+ ret = trace_remove_event_call(&tu->call);
+ if (ret)
+ return ret;
kfree(tu->call.print_fmt);
tu->call.print_fmt = NULL;
kfree(tu->call.print_fmt);
tu->call.print_fmt = NULL;
+ return 0;
}
/* Make a trace interface for controling probe points */
}
/* Make a trace interface for controling probe points */