Skip to content

Commit 4c1fd17

Browse files
Jacob ShinIngo Molnar
authored andcommitted
perf/x86: Move MSR address offset calculation to architecture specific files
Move counter index to MSR address offset calculation to architecture specific files. This prepares the way for perf_event_amd to enable counter addresses that are not contiguous -- for example AMD Family 15h processors have 6 core performance counters starting at 0xc0010200 and 4 northbridge performance counters starting at 0xc0010240. Signed-off-by: Jacob Shin <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 9f19010 commit 4c1fd17

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

arch/x86/kernel/cpu/perf_event.h

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ struct x86_pmu {
325325
int (*schedule_events)(struct cpu_hw_events *cpuc, int n, int *assign);
326326
unsigned eventsel;
327327
unsigned perfctr;
328+
int (*addr_offset)(int index, bool eventsel);
328329
u64 (*event_map)(int);
329330
int max_events;
330331
int num_counters;
@@ -446,28 +447,16 @@ extern u64 __read_mostly hw_cache_extra_regs
446447

447448
u64 x86_perf_event_update(struct perf_event *event);
448449

449-
static inline int x86_pmu_addr_offset(int index)
450-
{
451-
int offset;
452-
453-
/* offset = X86_FEATURE_PERFCTR_CORE ? index << 1 : index */
454-
alternative_io(ASM_NOP2,
455-
"shll $1, %%eax",
456-
X86_FEATURE_PERFCTR_CORE,
457-
"=a" (offset),
458-
"a" (index));
459-
460-
return offset;
461-
}
462-
463450
static inline unsigned int x86_pmu_config_addr(int index)
464451
{
465-
return x86_pmu.eventsel + x86_pmu_addr_offset(index);
452+
return x86_pmu.eventsel + (x86_pmu.addr_offset ?
453+
x86_pmu.addr_offset(index, true) : index);
466454
}
467455

468456
static inline unsigned int x86_pmu_event_addr(int index)
469457
{
470-
return x86_pmu.perfctr + x86_pmu_addr_offset(index);
458+
return x86_pmu.perfctr + (x86_pmu.addr_offset ?
459+
x86_pmu.addr_offset(index, false) : index);
471460
}
472461

473462
int x86_setup_perfctr(struct perf_event *event);

arch/x86/kernel/cpu/perf_event_amd.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,47 @@ static u64 amd_pmu_event_map(int hw_event)
132132
return amd_perfmon_event_map[hw_event];
133133
}
134134

135+
/*
136+
* Previously calculated offsets
137+
*/
138+
static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly;
139+
static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly;
140+
141+
/*
142+
* Legacy CPUs:
143+
* 4 counters starting at 0xc0010000 each offset by 1
144+
*
145+
* CPUs with core performance counter extensions:
146+
* 6 counters starting at 0xc0010200 each offset by 2
147+
*/
148+
static inline int amd_pmu_addr_offset(int index, bool eventsel)
149+
{
150+
int offset;
151+
152+
if (!index)
153+
return index;
154+
155+
if (eventsel)
156+
offset = event_offsets[index];
157+
else
158+
offset = count_offsets[index];
159+
160+
if (offset)
161+
return offset;
162+
163+
if (!cpu_has_perfctr_core)
164+
offset = index;
165+
else
166+
offset = index << 1;
167+
168+
if (eventsel)
169+
event_offsets[index] = offset;
170+
else
171+
count_offsets[index] = offset;
172+
173+
return offset;
174+
}
175+
135176
static int amd_pmu_hw_config(struct perf_event *event)
136177
{
137178
int ret;
@@ -578,6 +619,7 @@ static __initconst const struct x86_pmu amd_pmu = {
578619
.schedule_events = x86_schedule_events,
579620
.eventsel = MSR_K7_EVNTSEL0,
580621
.perfctr = MSR_K7_PERFCTR0,
622+
.addr_offset = amd_pmu_addr_offset,
581623
.event_map = amd_pmu_event_map,
582624
.max_events = ARRAY_SIZE(amd_perfmon_event_map),
583625
.num_counters = AMD64_NUM_COUNTERS,

0 commit comments

Comments
 (0)