Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 304894
b: refs/heads/master
c: 8b1e136
h: refs/heads/master
v: v3
  • Loading branch information
Robert Richter authored and Ingo Molnar committed May 9, 2012
1 parent ed823e6 commit 37b47c0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fc5fb2b5e1874e5894e2ac503bfb744220db89a1
refs/heads/master: 8b1e13638d465863572c8207a5cfceeef0cf0441
33 changes: 21 additions & 12 deletions trunk/arch/x86/kernel/cpu/perf_event_amd_ibs.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,15 @@ static u64 get_ibs_fetch_count(u64 config)

static u64 get_ibs_op_count(u64 config)
{
return (config & IBS_OP_CUR_CNT) >> 32;
u64 count = 0;

if (config & IBS_OP_VAL)
count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */

if (ibs_caps & IBS_CAPS_RDWROPCNT)
count += (config & IBS_OP_CUR_CNT) >> 32;

return count;
}

static void
Expand All @@ -295,7 +303,12 @@ perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
{
u64 count = perf_ibs->get_count(*config);

while (!perf_event_try_update(event, count, 20)) {
/*
* Set width to 64 since we do not overflow on max width but
* instead on max count. In perf_ibs_set_period() we clear
* prev count manually on overflow.
*/
while (!perf_event_try_update(event, count, 64)) {
rdmsrl(event->hw.config_base, *config);
count = perf_ibs->get_count(*config);
}
Expand Down Expand Up @@ -374,6 +387,12 @@ static void perf_ibs_stop(struct perf_event *event, int flags)
if (hwc->state & PERF_HES_UPTODATE)
return;

/*
* Clear valid bit to not count rollovers on update, rollovers
* are only updated in the irq handler.
*/
config &= ~perf_ibs->valid_mask;

perf_ibs_event_update(perf_ibs, event, &config);
hwc->state |= PERF_HES_UPTODATE;
}
Expand Down Expand Up @@ -488,17 +507,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
if (!(*buf++ & perf_ibs->valid_mask))
return 0;

/*
* Emulate IbsOpCurCnt in MSRC001_1033 (IbsOpCtl), not
* supported in all cpus. As this triggered an interrupt, we
* set the current count to the max count.
*/
config = &ibs_data.regs[0];
if (perf_ibs == &perf_ibs_op && !(ibs_caps & IBS_CAPS_RDWROPCNT)) {
*config &= ~IBS_OP_CUR_CNT;
*config |= (*config & IBS_OP_MAX_CNT) << 36;
}

perf_ibs_event_update(perf_ibs, event, config);
perf_sample_data_init(&data, 0, hwc->last_period);
if (!perf_ibs_set_period(perf_ibs, hwc, &period))
Expand Down

0 comments on commit 37b47c0

Please sign in to comment.