aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_ksym.c
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-11-27 04:55:54 +0100
committerIngo Molnar <mingo@elte.hu>2009-11-27 06:22:59 +0100
commitdd1853c3f493f6d22d9e5390b192a07b73d2ac0a (patch)
treeaf87226bcdc254ce2ab656530263e61f6552322b /kernel/trace/trace_ksym.c
parenthw-breakpoints: Use struct perf_event_attr to define user breakpoints (diff)
downloadlinux-dev-dd1853c3f493f6d22d9e5390b192a07b73d2ac0a.tar.xz
linux-dev-dd1853c3f493f6d22d9e5390b192a07b73d2ac0a.zip
hw-breakpoints: Use struct perf_event_attr to define kernel breakpoints
Kernel breakpoints are created using functions in which we pass breakpoint parameters as individual variables: address, length and type. Although it fits well for x86, this just does not scale across architectures that may support this api later as these may have more or different needs. Pass in a perf_event_attr structure instead because it is meant to evolve as much as possible into a generic hardware breakpoint parameter structure. Reported-by: K.Prasad <prasad@linux.vnet.ibm.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <1259294154-5197-2-git-send-regression-fweisbec@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace_ksym.c')
-rw-r--r--kernel/trace/trace_ksym.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index c538b15b95d6..ddfa0fd43bc0 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -42,9 +42,7 @@
struct trace_ksym {
struct perf_event **ksym_hbp;
- unsigned long ksym_addr;
- int type;
- int len;
+ struct perf_event_attr attr;
#ifdef CONFIG_PROFILE_KSYM_TRACER
unsigned long counter;
#endif
@@ -71,7 +69,7 @@ void ksym_collect_stats(unsigned long hbp_hit_addr)
rcu_read_lock();
hlist_for_each_entry_rcu(entry, node, &ksym_filter_head, ksym_hlist) {
- if ((entry->ksym_addr == hbp_hit_addr) &&
+ if ((entry->attr.bp_addr == hbp_hit_addr) &&
(entry->counter <= MAX_UL_INT)) {
entry->counter++;
break;
@@ -192,14 +190,15 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
if (!entry)
return -ENOMEM;
- entry->type = op;
- entry->ksym_addr = addr;
- entry->len = HW_BREAKPOINT_LEN_4;
+ hw_breakpoint_init(&entry->attr);
+
+ entry->attr.bp_type = op;
+ entry->attr.bp_addr = addr;
+ entry->attr.bp_len = HW_BREAKPOINT_LEN_4;
ret = -EAGAIN;
- entry->ksym_hbp = register_wide_hw_breakpoint(entry->ksym_addr,
- entry->len, entry->type,
- ksym_hbp_handler, true);
+ entry->ksym_hbp = register_wide_hw_breakpoint(&entry->attr,
+ ksym_hbp_handler);
if (IS_ERR(entry->ksym_hbp)) {
ret = PTR_ERR(entry->ksym_hbp);
@@ -236,12 +235,12 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf,
mutex_lock(&ksym_tracer_mutex);
hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
- ret = trace_seq_printf(s, "%pS:", (void *)entry->ksym_addr);
- if (entry->type == HW_BREAKPOINT_R)
+ ret = trace_seq_printf(s, "%pS:", (void *)entry->attr.bp_addr);
+ if (entry->attr.bp_type == HW_BREAKPOINT_R)
ret = trace_seq_puts(s, "r--\n");
- else if (entry->type == HW_BREAKPOINT_W)
+ else if (entry->attr.bp_type == HW_BREAKPOINT_W)
ret = trace_seq_puts(s, "-w-\n");
- else if (entry->type == (HW_BREAKPOINT_W | HW_BREAKPOINT_R))
+ else if (entry->attr.bp_type == (HW_BREAKPOINT_W | HW_BREAKPOINT_R))
ret = trace_seq_puts(s, "rw-\n");
WARN_ON_ONCE(!ret);
}
@@ -317,9 +316,9 @@ static ssize_t ksym_trace_filter_write(struct file *file,
ret = -EINVAL;
hlist_for_each_entry(entry, node, &ksym_filter_head, ksym_hlist) {
- if (entry->ksym_addr == ksym_addr) {
+ if (entry->attr.bp_addr == ksym_addr) {
/* Check for malformed request: (6) */
- if (entry->type != op)
+ if (entry->attr.bp_type != op)
changed = 1;
else
goto out;
@@ -328,13 +327,12 @@ static ssize_t ksym_trace_filter_write(struct file *file,
}
if (changed) {
unregister_wide_hw_breakpoint(entry->ksym_hbp);
- entry->type = op;
+ entry->attr.bp_type = op;
ret = 0;
if (op > 0) {
entry->ksym_hbp =
- register_wide_hw_breakpoint(entry->ksym_addr,
- entry->len, entry->type,
- ksym_hbp_handler, true);
+ register_wide_hw_breakpoint(&entry->attr,
+ ksym_hbp_handler);
if (IS_ERR(entry->ksym_hbp))
ret = PTR_ERR(entry->ksym_hbp);
else
@@ -489,7 +487,7 @@ static int ksym_tracer_stat_show(struct seq_file *m, void *v)
entry = hlist_entry(stat, struct trace_ksym, ksym_hlist);
- access_type = entry->type;
+ access_type = entry->attr.bp_type;
switch (access_type) {
case HW_BREAKPOINT_R:
@@ -505,7 +503,7 @@ static int ksym_tracer_stat_show(struct seq_file *m, void *v)
seq_puts(m, " NA ");
}
- if (lookup_symbol_name(entry->ksym_addr, fn_name) >= 0)
+ if (lookup_symbol_name(entry->attr.bp_addr, fn_name) >= 0)
seq_printf(m, " %-36s", fn_name);
else
seq_printf(m, " %-36s", "<NA>");