Skip to content

Commit 10b84da

Browse files
committed
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar: "Two fixlets" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/hwbp: Simplify the perf-hwbp code, fix documentation perf/x86/intel: Fix linear IP of PEBS real_ip on Haswell and later CPUs
2 parents ad0500c + f67b150 commit 10b84da

File tree

2 files changed

+24
-31
lines changed

2 files changed

+24
-31
lines changed

arch/x86/events/intel/ds.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,7 @@ static void setup_pebs_sample_data(struct perf_event *event,
11531153
if (pebs == NULL)
11541154
return;
11551155

1156+
regs->flags &= ~PERF_EFLAGS_EXACT;
11561157
sample_type = event->attr.sample_type;
11571158
dsrc = sample_type & PERF_SAMPLE_DATA_SRC;
11581159

@@ -1197,7 +1198,6 @@ static void setup_pebs_sample_data(struct perf_event *event,
11971198
*/
11981199
*regs = *iregs;
11991200
regs->flags = pebs->flags;
1200-
set_linear_ip(regs, pebs->ip);
12011201

12021202
if (sample_type & PERF_SAMPLE_REGS_INTR) {
12031203
regs->ax = pebs->ax;
@@ -1233,13 +1233,22 @@ static void setup_pebs_sample_data(struct perf_event *event,
12331233
#endif
12341234
}
12351235

1236-
if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
1237-
regs->ip = pebs->real_ip;
1238-
regs->flags |= PERF_EFLAGS_EXACT;
1239-
} else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
1240-
regs->flags |= PERF_EFLAGS_EXACT;
1241-
else
1242-
regs->flags &= ~PERF_EFLAGS_EXACT;
1236+
if (event->attr.precise_ip > 1) {
1237+
/* Haswell and later have the eventing IP, so use it: */
1238+
if (x86_pmu.intel_cap.pebs_format >= 2) {
1239+
set_linear_ip(regs, pebs->real_ip);
1240+
regs->flags |= PERF_EFLAGS_EXACT;
1241+
} else {
1242+
/* Otherwise use PEBS off-by-1 IP: */
1243+
set_linear_ip(regs, pebs->ip);
1244+
1245+
/* ... and try to fix it up using the LBR entries: */
1246+
if (intel_pmu_pebs_fixup_ip(regs))
1247+
regs->flags |= PERF_EFLAGS_EXACT;
1248+
}
1249+
} else
1250+
set_linear_ip(regs, pebs->ip);
1251+
12431252

12441253
if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) &&
12451254
x86_pmu.intel_cap.pebs_format >= 1)

kernel/events/hw_breakpoint.c

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -427,16 +427,9 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
427427
* modify_user_hw_breakpoint - modify a user-space hardware breakpoint
428428
* @bp: the breakpoint structure to modify
429429
* @attr: new breakpoint attributes
430-
* @triggered: callback to trigger when we hit the breakpoint
431-
* @tsk: pointer to 'task_struct' of the process to which the address belongs
432430
*/
433431
int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
434432
{
435-
u64 old_addr = bp->attr.bp_addr;
436-
u64 old_len = bp->attr.bp_len;
437-
int old_type = bp->attr.bp_type;
438-
int err = 0;
439-
440433
/*
441434
* modify_user_hw_breakpoint can be invoked with IRQs disabled and hence it
442435
* will not be possible to raise IPIs that invoke __perf_event_disable.
@@ -451,27 +444,18 @@ int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *att
451444
bp->attr.bp_addr = attr->bp_addr;
452445
bp->attr.bp_type = attr->bp_type;
453446
bp->attr.bp_len = attr->bp_len;
447+
bp->attr.disabled = 1;
454448

455-
if (attr->disabled)
456-
goto end;
457-
458-
err = validate_hw_breakpoint(bp);
459-
if (!err)
460-
perf_event_enable(bp);
449+
if (!attr->disabled) {
450+
int err = validate_hw_breakpoint(bp);
461451

462-
if (err) {
463-
bp->attr.bp_addr = old_addr;
464-
bp->attr.bp_type = old_type;
465-
bp->attr.bp_len = old_len;
466-
if (!bp->attr.disabled)
467-
perf_event_enable(bp);
452+
if (err)
453+
return err;
468454

469-
return err;
455+
perf_event_enable(bp);
456+
bp->attr.disabled = 0;
470457
}
471458

472-
end:
473-
bp->attr.disabled = attr->disabled;
474-
475459
return 0;
476460
}
477461
EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint);

0 commit comments

Comments
 (0)