* [PATCH 2/3] hw-breakpoints: Improve in-kernel event creation error granularity
2009-11-26 4:35 [PATCH 1/3] ksym_tracer: Fix breakpoint removal after modification Frederic Weisbecker
@ 2009-11-26 4:35 ` Frederic Weisbecker
2009-11-26 8:44 ` [tip:perf/core] " tip-bot for Frederic Weisbecker
2009-11-26 4:35 ` [PATCH 3/3] hw-breakpoints: Simplify error handling in breakpoint creation requests Frederic Weisbecker
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Frederic Weisbecker @ 2009-11-26 4:35 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, Frederic Weisbecker, Peter Zijlstra,
Arnaldo Carvalho de Melo, Paul Mackerras, Prasad
In fail case, perf_event_create_kernel_counter() returns NULL instead
of an error, which doesn't help us to inform the user about the origin
of the problem from the outer most callers. Often we can just return
-EINVAL, which doesn't help anyone when it's eventually about a memory
allocation failure.
Then, this patch makes perf_event_create_kernel_counter() always
returning a detailed error code.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Prasad <prasad@linux.vnet.ibm.com>
---
kernel/perf_event.c | 20 +++++++++++---------
1 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 35df94e..34a1b9d 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -4780,14 +4780,17 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
*/
ctx = find_get_context(pid, cpu);
- if (IS_ERR(ctx))
- return NULL;
+ if (IS_ERR(ctx)) {
+ err = PTR_ERR(ctx);
+ goto err_exit;
+ }
event = perf_event_alloc(attr, cpu, ctx, NULL,
NULL, callback, GFP_KERNEL);
- err = PTR_ERR(event);
- if (IS_ERR(event))
+ if (IS_ERR(event)) {
+ err = PTR_ERR(event);
goto err_put_context;
+ }
event->filp = NULL;
WARN_ON_ONCE(ctx->parent_ctx);
@@ -4804,11 +4807,10 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
return event;
-err_put_context:
- if (err < 0)
- put_ctx(ctx);
-
- return NULL;
+ err_put_context:
+ put_ctx(ctx);
+ err_exit:
+ return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
--
1.6.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [tip:perf/core] hw-breakpoints: Improve in-kernel event creation error granularity
2009-11-26 4:35 ` [PATCH 2/3] hw-breakpoints: Improve in-kernel event creation error granularity Frederic Weisbecker
@ 2009-11-26 8:44 ` tip-bot for Frederic Weisbecker
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-11-26 8:44 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, paulus, acme, hpa, mingo, peterz, fweisbec, tglx,
mingo, prasad
Commit-ID: c6567f642e20bcc79abed030f44be5b0d6da2ded
Gitweb: http://git.kernel.org/tip/c6567f642e20bcc79abed030f44be5b0d6da2ded
Author: Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 26 Nov 2009 05:35:41 +0100
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 26 Nov 2009 09:29:21 +0100
hw-breakpoints: Improve in-kernel event creation error granularity
In fail case, perf_event_create_kernel_counter() returns NULL
instead of an error, which doesn't help us to inform the user
about the origin of the problem from the outer most callers.
Often we can just return -EINVAL, which doesn't help anyone when
it's eventually about a memory allocation failure.
Then, this patch makes perf_event_create_kernel_counter() always
return a detailed error code.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Prasad <prasad@linux.vnet.ibm.com>
LKML-Reference: <1259210142-5714-2-git-send-regression-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/perf_event.c | 20 +++++++++++---------
1 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 35df94e..34a1b9d 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -4780,14 +4780,17 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
*/
ctx = find_get_context(pid, cpu);
- if (IS_ERR(ctx))
- return NULL;
+ if (IS_ERR(ctx)) {
+ err = PTR_ERR(ctx);
+ goto err_exit;
+ }
event = perf_event_alloc(attr, cpu, ctx, NULL,
NULL, callback, GFP_KERNEL);
- err = PTR_ERR(event);
- if (IS_ERR(event))
+ if (IS_ERR(event)) {
+ err = PTR_ERR(event);
goto err_put_context;
+ }
event->filp = NULL;
WARN_ON_ONCE(ctx->parent_ctx);
@@ -4804,11 +4807,10 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu,
return event;
-err_put_context:
- if (err < 0)
- put_ctx(ctx);
-
- return NULL;
+ err_put_context:
+ put_ctx(ctx);
+ err_exit:
+ return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(perf_event_create_kernel_counter);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] hw-breakpoints: Simplify error handling in breakpoint creation requests
2009-11-26 4:35 [PATCH 1/3] ksym_tracer: Fix breakpoint removal after modification Frederic Weisbecker
2009-11-26 4:35 ` [PATCH 2/3] hw-breakpoints: Improve in-kernel event creation error granularity Frederic Weisbecker
@ 2009-11-26 4:35 ` Frederic Weisbecker
2009-11-26 8:45 ` [tip:perf/core] " tip-bot for Frederic Weisbecker
2009-11-26 5:04 ` [PATCH 4/3] x86/hw-breakpoints: Don't lose GE flag while disabling a breakpoint Frederic Weisbecker
2009-11-26 8:44 ` [tip:perf/core] ksym_tracer: Fix breakpoint removal after modification tip-bot for Frederic Weisbecker
3 siblings, 1 reply; 8+ messages in thread
From: Frederic Weisbecker @ 2009-11-26 4:35 UTC (permalink / raw)
To: Ingo Molnar
Cc: LKML, Frederic Weisbecker, Peter Zijlstra,
Arnaldo Carvalho de Melo, Paul Mackerras, Steven Rostedt, Prasad
This simplifies the error handling when we create a breakpoint.
We don't need anymore to check the NULL return value corner case
since we have improved perf_event_create_kernel_counter() to
always return an error code in fail case.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Prasad <prasad@linux.vnet.ibm.com>
---
arch/x86/kernel/ptrace.c | 8 +-------
kernel/hw_breakpoint.c | 4 ++--
kernel/trace/trace_ksym.c | 16 ++++------------
samples/hw_breakpoint/data_breakpoint.c | 3 ---
4 files changed, 7 insertions(+), 24 deletions(-)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index b25f894..75e0cd8 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -657,10 +657,7 @@ restore:
tsk, true);
thread->ptrace_bps[i] = NULL;
- if (!bp) { /* incorrect bp, or we have a bug in bp API */
- rc = -EINVAL;
- break;
- }
+ /* Incorrect bp, or we have a bug in bp API */
if (IS_ERR(bp)) {
rc = PTR_ERR(bp);
bp = NULL;
@@ -729,9 +726,6 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
tsk,
bp->attr.disabled);
}
-
- if (!bp)
- return -EIO;
/*
* CHECKME: the previous code returned -EIO if the addr wasn't a
* valid task virtual addr. The new one will return -EINVAL in this
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 06d372f..dd3fb4a 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -442,7 +442,7 @@ register_wide_hw_breakpoint(unsigned long addr,
*pevent = bp;
- if (IS_ERR(bp) || !bp) {
+ if (IS_ERR(bp)) {
err = PTR_ERR(bp);
goto fail;
}
@@ -453,7 +453,7 @@ register_wide_hw_breakpoint(unsigned long addr,
fail:
for_each_possible_cpu(cpu) {
pevent = per_cpu_ptr(cpu_events, cpu);
- if (IS_ERR(*pevent) || !*pevent)
+ if (IS_ERR(*pevent))
break;
unregister_hw_breakpoint(*pevent);
}
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index 9f040e4..c538b15 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -200,12 +200,9 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
entry->ksym_hbp = register_wide_hw_breakpoint(entry->ksym_addr,
entry->len, entry->type,
ksym_hbp_handler, true);
+
if (IS_ERR(entry->ksym_hbp)) {
- entry->ksym_hbp = NULL;
ret = PTR_ERR(entry->ksym_hbp);
- }
-
- if (!entry->ksym_hbp) {
printk(KERN_INFO "ksym_tracer request failed. Try again"
" later!!\n");
goto err;
@@ -332,21 +329,16 @@ static ssize_t ksym_trace_filter_write(struct file *file,
if (changed) {
unregister_wide_hw_breakpoint(entry->ksym_hbp);
entry->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);
if (IS_ERR(entry->ksym_hbp))
- entry->ksym_hbp = NULL;
-
- /* modified without problem */
- if (entry->ksym_hbp) {
- ret = 0;
+ ret = PTR_ERR(entry->ksym_hbp);
+ else
goto out;
- }
- } else {
- ret = 0;
}
/* Error or "symbol:---" case: drop it */
ksym_filter_entry_count--;
diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
index 9506381..ee7f9fb 100644
--- a/samples/hw_breakpoint/data_breakpoint.c
+++ b/samples/hw_breakpoint/data_breakpoint.c
@@ -61,9 +61,6 @@ static int __init hw_break_module_init(void)
if (IS_ERR(sample_hbp)) {
ret = PTR_ERR(sample_hbp);
goto fail;
- } else if (!sample_hbp) {
- ret = -EINVAL;
- goto fail;
}
printk(KERN_INFO "HW Breakpoint for %s write installed\n", ksym_name);
--
1.6.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [tip:perf/core] hw-breakpoints: Simplify error handling in breakpoint creation requests
2009-11-26 4:35 ` [PATCH 3/3] hw-breakpoints: Simplify error handling in breakpoint creation requests Frederic Weisbecker
@ 2009-11-26 8:45 ` tip-bot for Frederic Weisbecker
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-11-26 8:45 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, paulus, acme, hpa, mingo, peterz, fweisbec, rostedt,
tglx, mingo, prasad
Commit-ID: 605bfaee9078cd0b01d83402315389839ee4bb5c
Gitweb: http://git.kernel.org/tip/605bfaee9078cd0b01d83402315389839ee4bb5c
Author: Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 26 Nov 2009 05:35:42 +0100
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 26 Nov 2009 09:29:21 +0100
hw-breakpoints: Simplify error handling in breakpoint creation requests
This simplifies the error handling when we create a breakpoint.
We don't need to check the NULL return value corner case anymore
since we have improved perf_event_create_kernel_counter() to
always return an error code in the failure case.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Prasad <prasad@linux.vnet.ibm.com>
LKML-Reference: <1259210142-5714-3-git-send-regression-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/ptrace.c | 8 +-------
kernel/hw_breakpoint.c | 4 ++--
kernel/trace/trace_ksym.c | 16 ++++------------
samples/hw_breakpoint/data_breakpoint.c | 3 ---
4 files changed, 7 insertions(+), 24 deletions(-)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index b25f894..75e0cd8 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -657,10 +657,7 @@ restore:
tsk, true);
thread->ptrace_bps[i] = NULL;
- if (!bp) { /* incorrect bp, or we have a bug in bp API */
- rc = -EINVAL;
- break;
- }
+ /* Incorrect bp, or we have a bug in bp API */
if (IS_ERR(bp)) {
rc = PTR_ERR(bp);
bp = NULL;
@@ -729,9 +726,6 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr,
tsk,
bp->attr.disabled);
}
-
- if (!bp)
- return -EIO;
/*
* CHECKME: the previous code returned -EIO if the addr wasn't a
* valid task virtual addr. The new one will return -EINVAL in this
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 06d372f..dd3fb4a 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -442,7 +442,7 @@ register_wide_hw_breakpoint(unsigned long addr,
*pevent = bp;
- if (IS_ERR(bp) || !bp) {
+ if (IS_ERR(bp)) {
err = PTR_ERR(bp);
goto fail;
}
@@ -453,7 +453,7 @@ register_wide_hw_breakpoint(unsigned long addr,
fail:
for_each_possible_cpu(cpu) {
pevent = per_cpu_ptr(cpu_events, cpu);
- if (IS_ERR(*pevent) || !*pevent)
+ if (IS_ERR(*pevent))
break;
unregister_hw_breakpoint(*pevent);
}
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index 9f040e4..c538b15 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -200,12 +200,9 @@ int process_new_ksym_entry(char *ksymname, int op, unsigned long addr)
entry->ksym_hbp = register_wide_hw_breakpoint(entry->ksym_addr,
entry->len, entry->type,
ksym_hbp_handler, true);
+
if (IS_ERR(entry->ksym_hbp)) {
- entry->ksym_hbp = NULL;
ret = PTR_ERR(entry->ksym_hbp);
- }
-
- if (!entry->ksym_hbp) {
printk(KERN_INFO "ksym_tracer request failed. Try again"
" later!!\n");
goto err;
@@ -332,21 +329,16 @@ static ssize_t ksym_trace_filter_write(struct file *file,
if (changed) {
unregister_wide_hw_breakpoint(entry->ksym_hbp);
entry->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);
if (IS_ERR(entry->ksym_hbp))
- entry->ksym_hbp = NULL;
-
- /* modified without problem */
- if (entry->ksym_hbp) {
- ret = 0;
+ ret = PTR_ERR(entry->ksym_hbp);
+ else
goto out;
- }
- } else {
- ret = 0;
}
/* Error or "symbol:---" case: drop it */
ksym_filter_entry_count--;
diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c
index 9506381..ee7f9fb 100644
--- a/samples/hw_breakpoint/data_breakpoint.c
+++ b/samples/hw_breakpoint/data_breakpoint.c
@@ -61,9 +61,6 @@ static int __init hw_break_module_init(void)
if (IS_ERR(sample_hbp)) {
ret = PTR_ERR(sample_hbp);
goto fail;
- } else if (!sample_hbp) {
- ret = -EINVAL;
- goto fail;
}
printk(KERN_INFO "HW Breakpoint for %s write installed\n", ksym_name);
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/3] x86/hw-breakpoints: Don't lose GE flag while disabling a breakpoint
2009-11-26 4:35 [PATCH 1/3] ksym_tracer: Fix breakpoint removal after modification Frederic Weisbecker
2009-11-26 4:35 ` [PATCH 2/3] hw-breakpoints: Improve in-kernel event creation error granularity Frederic Weisbecker
2009-11-26 4:35 ` [PATCH 3/3] hw-breakpoints: Simplify error handling in breakpoint creation requests Frederic Weisbecker
@ 2009-11-26 5:04 ` Frederic Weisbecker
2009-11-26 8:45 ` [tip:perf/core] " tip-bot for Frederic Weisbecker
2009-11-26 8:44 ` [tip:perf/core] ksym_tracer: Fix breakpoint removal after modification tip-bot for Frederic Weisbecker
3 siblings, 1 reply; 8+ messages in thread
From: Frederic Weisbecker @ 2009-11-26 5:04 UTC (permalink / raw)
To: Ingo Molnar; +Cc: LKML, Frederic Weisbecker, Prasad
When we schedule out a breakpoint from the cpu, we also incidentally
remove the "Global exact breakpoint" flag from the breakpoint control
register. It makes us losing the fine grained precision about the
origin of the instructions that may trigger breakpoint exceptions for
the other breakpoints running in this cpu.
Reported-by: Prasad <prasad@linux.vnet.ibm.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
---
arch/x86/kernel/hw_breakpoint.c | 22 ++++++++++++++--------
1 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index 92ea5aa..d42f65a 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -59,22 +59,28 @@ static DEFINE_PER_CPU(unsigned long, cpu_debugreg[HBP_NUM]);
static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
-/*
- * Encode the length, type, Exact, and Enable bits for a particular breakpoint
- * as stored in debug register 7.
- */
-unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
+static inline unsigned long
+__encode_dr7(int drnum, unsigned int len, unsigned int type)
{
unsigned long bp_info;
bp_info = (len | type) & 0xf;
bp_info <<= (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
- bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE)) |
- DR_GLOBAL_SLOWDOWN;
+ bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));
+
return bp_info;
}
/*
+ * Encode the length, type, Exact, and Enable bits for a particular breakpoint
+ * as stored in debug register 7.
+ */
+unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
+{
+ return __encode_dr7(drnum, len, type) | DR_GLOBAL_SLOWDOWN;
+}
+
+/*
* Decode the length and type bits for a particular breakpoint as
* stored in debug register 7. Return the "enabled" status.
*/
@@ -154,7 +160,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
return;
dr7 = &__get_cpu_var(cpu_dr7);
- *dr7 &= ~encode_dr7(i, info->len, info->type);
+ *dr7 &= ~__encode_dr7(i, info->len, info->type);
set_debugreg(*dr7, 7);
}
--
1.6.2.3
^ permalink raw reply related [flat|nested] 8+ messages in thread* [tip:perf/core] x86/hw-breakpoints: Don't lose GE flag while disabling a breakpoint
2009-11-26 5:04 ` [PATCH 4/3] x86/hw-breakpoints: Don't lose GE flag while disabling a breakpoint Frederic Weisbecker
@ 2009-11-26 8:45 ` tip-bot for Frederic Weisbecker
0 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-11-26 8:45 UTC (permalink / raw)
To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, fweisbec, tglx, mingo, prasad
Commit-ID: 2c31b7958fd21df9fa04e5c36cda0f063ac70b27
Gitweb: http://git.kernel.org/tip/2c31b7958fd21df9fa04e5c36cda0f063ac70b27
Author: Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 26 Nov 2009 06:04:38 +0100
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 26 Nov 2009 09:29:22 +0100
x86/hw-breakpoints: Don't lose GE flag while disabling a breakpoint
When we schedule out a breakpoint from the cpu, we also
incidentally remove the "Global exact breakpoint" flag from the
breakpoint control register. It makes us losing the fine grained
precision about the origin of the instructions that may trigger
breakpoint exceptions for the other breakpoints running in this
cpu.
Reported-by: Prasad <prasad@linux.vnet.ibm.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <1259211878-6013-1-git-send-regression-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/hw_breakpoint.c | 22 ++++++++++++++--------
1 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index 92ea5aa..d42f65a 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -59,22 +59,28 @@ static DEFINE_PER_CPU(unsigned long, cpu_debugreg[HBP_NUM]);
static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
-/*
- * Encode the length, type, Exact, and Enable bits for a particular breakpoint
- * as stored in debug register 7.
- */
-unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
+static inline unsigned long
+__encode_dr7(int drnum, unsigned int len, unsigned int type)
{
unsigned long bp_info;
bp_info = (len | type) & 0xf;
bp_info <<= (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
- bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE)) |
- DR_GLOBAL_SLOWDOWN;
+ bp_info |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));
+
return bp_info;
}
/*
+ * Encode the length, type, Exact, and Enable bits for a particular breakpoint
+ * as stored in debug register 7.
+ */
+unsigned long encode_dr7(int drnum, unsigned int len, unsigned int type)
+{
+ return __encode_dr7(drnum, len, type) | DR_GLOBAL_SLOWDOWN;
+}
+
+/*
* Decode the length and type bits for a particular breakpoint as
* stored in debug register 7. Return the "enabled" status.
*/
@@ -154,7 +160,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
return;
dr7 = &__get_cpu_var(cpu_dr7);
- *dr7 &= ~encode_dr7(i, info->len, info->type);
+ *dr7 &= ~__encode_dr7(i, info->len, info->type);
set_debugreg(*dr7, 7);
}
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [tip:perf/core] ksym_tracer: Fix breakpoint removal after modification
2009-11-26 4:35 [PATCH 1/3] ksym_tracer: Fix breakpoint removal after modification Frederic Weisbecker
` (2 preceding siblings ...)
2009-11-26 5:04 ` [PATCH 4/3] x86/hw-breakpoints: Don't lose GE flag while disabling a breakpoint Frederic Weisbecker
@ 2009-11-26 8:44 ` tip-bot for Frederic Weisbecker
3 siblings, 0 replies; 8+ messages in thread
From: tip-bot for Frederic Weisbecker @ 2009-11-26 8:44 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, hpa, mingo, fweisbec, rostedt, tglx, prasad, mingo
Commit-ID: d99be40aff88722ab03ee295e4f6c13a4cca9a3d
Gitweb: http://git.kernel.org/tip/d99be40aff88722ab03ee295e4f6c13a4cca9a3d
Author: Frederic Weisbecker <fweisbec@gmail.com>
AuthorDate: Thu, 26 Nov 2009 05:35:40 +0100
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 26 Nov 2009 09:29:20 +0100
ksym_tracer: Fix breakpoint removal after modification
The error path of a breakpoint modification is broken in
the ksym tracer. A modified breakpoint hlist node is immediately
released after its removal. Also we leak a breakpoint in this
case.
Fix the path.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Prasad <prasad@linux.vnet.ibm.com>
LKML-Reference: <1259210142-5714-1-git-send-regression-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
kernel/trace/trace_ksym.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c
index 11935b5..9f040e4 100644
--- a/kernel/trace/trace_ksym.c
+++ b/kernel/trace/trace_ksym.c
@@ -339,14 +339,20 @@ static ssize_t ksym_trace_filter_write(struct file *file,
ksym_hbp_handler, true);
if (IS_ERR(entry->ksym_hbp))
entry->ksym_hbp = NULL;
- if (!entry->ksym_hbp)
+
+ /* modified without problem */
+ if (entry->ksym_hbp) {
+ ret = 0;
goto out;
+ }
+ } else {
+ ret = 0;
}
+ /* Error or "symbol:---" case: drop it */
ksym_filter_entry_count--;
hlist_del_rcu(&(entry->ksym_hlist));
synchronize_rcu();
kfree(entry);
- ret = 0;
goto out;
} else {
/* Check for malformed request: (4) */
^ permalink raw reply related [flat|nested] 8+ messages in thread