Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 350052
b: refs/heads/master
c: 4c1fd17
h: refs/heads/master
v: v3
  • Loading branch information
Jacob Shin authored and Ingo Molnar committed Feb 6, 2013
1 parent 3e2b493 commit 89cdb59
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 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: 9f19010af8c651879ac2c36f1a808a3a4419cd40
refs/heads/master: 4c1fd17a1cb32bc4f429c7a5ff9a91a3bffdb8fa
21 changes: 5 additions & 16 deletions trunk/arch/x86/kernel/cpu/perf_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ struct x86_pmu {
int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
unsigned eventsel;
unsigned perfctr;
int (*addr_offset)(int index, bool eventsel);
u64 (*event_map)(int);
int max_events;
int num_counters;
Expand Down Expand Up @@ -446,28 +447,16 @@ extern u64 __read_mostly hw_cache_extra_regs

u64 x86_perf_event_update(struct perf_event *event);

static inline int x86_pmu_addr_offset(int index)
{
int offset;

/* offset = X86_FEATURE_PERFCTR_CORE ? index << 1 : index */
alternative_io(ASM_NOP2,
"shll $1, %%eax",
X86_FEATURE_PERFCTR_CORE,
"=a" (offset),
"a" (index));

return offset;
}

static inline unsigned int x86_pmu_config_addr(int index)
{
return x86_pmu.eventsel + x86_pmu_addr_offset(index);
return x86_pmu.eventsel + (x86_pmu.addr_offset ?
x86_pmu.addr_offset(index, true) : index);
}

static inline unsigned int x86_pmu_event_addr(int index)
{
return x86_pmu.perfctr + x86_pmu_addr_offset(index);
return x86_pmu.perfctr + (x86_pmu.addr_offset ?
x86_pmu.addr_offset(index, false) : index);
}

int x86_setup_perfctr(struct perf_event *event);
Expand Down
42 changes: 42 additions & 0 deletions trunk/arch/x86/kernel/cpu/perf_event_amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,47 @@ static u64 amd_pmu_event_map(int hw_event)
return amd_perfmon_event_map[hw_event];
}

/*
* Previously calculated offsets
*/
static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly;
static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly;

/*
* Legacy CPUs:
* 4 counters starting at 0xc0010000 each offset by 1
*
* CPUs with core performance counter extensions:
* 6 counters starting at 0xc0010200 each offset by 2
*/
static inline int amd_pmu_addr_offset(int index, bool eventsel)
{
int offset;

if (!index)
return index;

if (eventsel)
offset = event_offsets[index];
else
offset = count_offsets[index];

if (offset)
return offset;

if (!cpu_has_perfctr_core)
offset = index;
else
offset = index << 1;

if (eventsel)
event_offsets[index] = offset;
else
count_offsets[index] = offset;

return offset;
}

static int amd_pmu_hw_config(struct perf_event *event)
{
int ret;
Expand Down Expand Up @@ -578,6 +619,7 @@ static __initconst const struct x86_pmu amd_pmu = {
.schedule_events = x86_schedule_events,
.eventsel = MSR_K7_EVNTSEL0,
.perfctr = MSR_K7_PERFCTR0,
.addr_offset = amd_pmu_addr_offset,
.event_map = amd_pmu_event_map,
.max_events = ARRAY_SIZE(amd_perfmon_event_map),
.num_counters = AMD64_NUM_COUNTERS,
Expand Down

0 comments on commit 89cdb59

Please sign in to comment.