Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
5a289395
Commit
5a289395
authored
Oct 15, 2008
by
Robert Richter
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'oprofile/x86-oprofile-for-tip' into oprofile/oprofile-for-tip
Conflicts: arch/x86/oprofile/op_model_ppro.c
parents
5f87dfb7
59512900
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
108 additions
and
35 deletions
+108
-35
arch/x86/oprofile/nmi_int.c
arch/x86/oprofile/nmi_int.c
+17
-9
arch/x86/oprofile/op_model_ppro.c
arch/x86/oprofile/op_model_ppro.c
+85
-23
arch/x86/oprofile/op_x86_model.h
arch/x86/oprofile/op_x86_model.h
+6
-3
No files found.
arch/x86/oprofile/nmi_int.c
View file @
5a289395
...
...
@@ -415,9 +415,6 @@ static int __init ppro_init(char **cpu_type)
case
15
:
case
23
:
*
cpu_type
=
"i386/core_2"
;
break
;
case
26
:
*
cpu_type
=
"i386/core_2"
;
break
;
default:
/* Unknown */
return
0
;
...
...
@@ -427,6 +424,16 @@ static int __init ppro_init(char **cpu_type)
return
1
;
}
static
int
__init
arch_perfmon_init
(
char
**
cpu_type
)
{
if
(
!
cpu_has_arch_perfmon
)
return
0
;
*
cpu_type
=
"i386/arch_perfmon"
;
model
=
&
op_arch_perfmon_spec
;
arch_perfmon_setup_counters
();
return
1
;
}
/* in order to get sysfs right */
static
int
using_nmi
;
...
...
@@ -434,7 +441,7 @@ int __init op_nmi_init(struct oprofile_operations *ops)
{
__u8
vendor
=
boot_cpu_data
.
x86_vendor
;
__u8
family
=
boot_cpu_data
.
x86
;
char
*
cpu_type
;
char
*
cpu_type
=
NULL
;
int
ret
=
0
;
if
(
!
cpu_has_apic
)
...
...
@@ -472,19 +479,20 @@ int __init op_nmi_init(struct oprofile_operations *ops)
switch
(
family
)
{
/* Pentium IV */
case
0xf
:
if
(
!
p4_init
(
&
cpu_type
))
return
-
ENODEV
;
p4_init
(
&
cpu_type
);
break
;
/* A P6-class processor */
case
6
:
if
(
!
ppro_init
(
&
cpu_type
))
return
-
ENODEV
;
ppro_init
(
&
cpu_type
);
break
;
default:
return
-
ENODEV
;
break
;
}
if
(
!
cpu_type
&&
!
arch_perfmon_init
(
&
cpu_type
))
return
-
ENODEV
;
break
;
default:
...
...
arch/x86/oprofile/op_model_ppro.c
View file @
5a289395
/*
* @file op_model_ppro.h
*
pentium pro / P6 model-specific
MSR operations
*
Family 6 perfmon and architectural perfmon
MSR operations
*
* @remark Copyright 2002 OProfile authors
* @remark Copyright 2008 Intel Corporation
* @remark Read the file COPYING
*
* @author John Levon
* @author Philippe Elie
* @author Graydon Hoare
* @author Andi Kleen
*/
#include <linux/oprofile.h>
#include <linux/slab.h>
#include <asm/ptrace.h>
#include <asm/msr.h>
#include <asm/apic.h>
#include <asm/nmi.h>
#include <asm/intel_arch_perfmon.h>
#include "op_x86_model.h"
#include "op_counter.h"
#define NUM_COUNTERS 2
#define NUM_CONTROLS 2
static
int
num_counters
=
2
;
static
int
counter_width
=
32
;
#define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
#define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0)
#define CTR_32BIT_WRITE(l, msrs, c) \
do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), 0); } while (0)
#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
#define CTR_OVERFLOWED(n) (!((n) & (1U<<(counter_width-1))))
#define CTRL_IS_RESERVED(msrs, c) (msrs->controls[(c)].addr ? 1 : 0)
#define CTRL_READ(l, h, msrs, c) do {rdmsr((msrs->controls[(c)].addr), (l), (h)); } while (0)
...
...
@@ -40,20 +42,20 @@
#define CTRL_SET_UM(val, m) (val |= (m << 8))
#define CTRL_SET_EVENT(val, e) (val |= e)
static
u
nsigned
long
reset_value
[
NUM_COUNTERS
]
;
static
u
64
*
reset_value
;
static
void
ppro_fill_in_addresses
(
struct
op_msrs
*
const
msrs
)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
i
++
)
{
for
(
i
=
0
;
i
<
num_counters
;
i
++
)
{
if
(
reserve_perfctr_nmi
(
MSR_P6_PERFCTR0
+
i
))
msrs
->
counters
[
i
].
addr
=
MSR_P6_PERFCTR0
+
i
;
else
msrs
->
counters
[
i
].
addr
=
0
;
}
for
(
i
=
0
;
i
<
NUM_CONTROLS
;
i
++
)
{
for
(
i
=
0
;
i
<
num_counters
;
i
++
)
{
if
(
reserve_evntsel_nmi
(
MSR_P6_EVNTSEL0
+
i
))
msrs
->
controls
[
i
].
addr
=
MSR_P6_EVNTSEL0
+
i
;
else
...
...
@@ -67,8 +69,22 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
unsigned
int
low
,
high
;
int
i
;
if
(
!
reset_value
)
{
reset_value
=
kmalloc
(
sizeof
(
unsigned
)
*
num_counters
,
GFP_ATOMIC
);
if
(
!
reset_value
)
return
;
}
if
(
cpu_has_arch_perfmon
)
{
union
cpuid10_eax
eax
;
eax
.
full
=
cpuid_eax
(
0xa
);
if
(
counter_width
<
eax
.
split
.
bit_width
)
counter_width
=
eax
.
split
.
bit_width
;
}
/* clear all counters */
for
(
i
=
0
;
i
<
NUM_CONTROLS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
unlikely
(
!
CTRL_IS_RESERVED
(
msrs
,
i
)))
continue
;
CTRL_READ
(
low
,
high
,
msrs
,
i
);
...
...
@@ -77,18 +93,18 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
}
/* avoid a false detection of ctr overflows in NMI handler */
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
unlikely
(
!
CTR_IS_RESERVED
(
msrs
,
i
)))
continue
;
CTR_32BIT_WRITE
(
1
,
msrs
,
i
);
wrmsrl
(
msrs
->
counters
[
i
].
addr
,
-
1LL
);
}
/* enable active counters */
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
((
counter_config
[
i
].
enabled
)
&&
(
CTR_IS_RESERVED
(
msrs
,
i
)))
{
reset_value
[
i
]
=
counter_config
[
i
].
count
;
CTR_32BIT_WRITE
(
counter_config
[
i
].
count
,
msrs
,
i
);
wrmsrl
(
msrs
->
counters
[
i
].
addr
,
-
reset_value
[
i
]
);
CTRL_READ
(
low
,
high
,
msrs
,
i
);
CTRL_CLEAR
(
low
);
...
...
@@ -111,13 +127,13 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
unsigned
int
low
,
high
;
int
i
;
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
!
reset_value
[
i
])
continue
;
CTR_READ
(
low
,
high
,
msrs
,
i
);
if
(
CTR_OVERFLOWED
(
low
))
{
oprofile_add_sample
(
regs
,
i
);
CTR_32BIT_WRITE
(
reset_value
[
i
],
msrs
,
i
);
wrmsrl
(
msrs
->
counters
[
i
].
addr
,
-
reset_value
[
i
]
);
}
}
...
...
@@ -141,7 +157,7 @@ static void ppro_start(struct op_msrs const * const msrs)
unsigned
int
low
,
high
;
int
i
;
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
reset_value
[
i
])
{
CTRL_READ
(
low
,
high
,
msrs
,
i
);
CTRL_SET_ACTIVE
(
low
);
...
...
@@ -156,7 +172,7 @@ static void ppro_stop(struct op_msrs const * const msrs)
unsigned
int
low
,
high
;
int
i
;
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
!
reset_value
[
i
])
continue
;
CTRL_READ
(
low
,
high
,
msrs
,
i
);
...
...
@@ -169,21 +185,67 @@ static void ppro_shutdown(struct op_msrs const * const msrs)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_COUNTERS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
CTR_IS_RESERVED
(
msrs
,
i
))
release_perfctr_nmi
(
MSR_P6_PERFCTR0
+
i
);
}
for
(
i
=
0
;
i
<
NUM_CONTROLS
;
++
i
)
{
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
if
(
CTRL_IS_RESERVED
(
msrs
,
i
))
release_evntsel_nmi
(
MSR_P6_EVNTSEL0
+
i
);
}
if
(
reset_value
)
{
kfree
(
reset_value
);
reset_value
=
NULL
;
}
}
struct
op_x86_model_spec
const
op_ppro_spec
=
{
.
num_counters
=
NUM_COUNTERS
,
.
num_controls
=
NUM_CONTROLS
,
struct
op_x86_model_spec
op_ppro_spec
=
{
.
num_counters
=
2
,
/* can be overriden */
.
num_controls
=
2
,
/* dito */
.
fill_in_addresses
=
&
ppro_fill_in_addresses
,
.
setup_ctrs
=
&
ppro_setup_ctrs
,
.
check_ctrs
=
&
ppro_check_ctrs
,
.
start
=
&
ppro_start
,
.
stop
=
&
ppro_stop
,
.
shutdown
=
&
ppro_shutdown
};
/*
* Architectural performance monitoring.
*
* Newer Intel CPUs (Core1+) have support for architectural
* events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details.
* The advantage of this is that it can be done without knowing about
* the specific CPU.
*/
void
arch_perfmon_setup_counters
(
void
)
{
union
cpuid10_eax
eax
;
eax
.
full
=
cpuid_eax
(
0xa
);
/* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */
if
(
eax
.
split
.
version_id
==
0
&&
current_cpu_data
.
x86
==
6
&&
current_cpu_data
.
x86_model
==
15
)
{
eax
.
split
.
version_id
=
2
;
eax
.
split
.
num_counters
=
2
;
eax
.
split
.
bit_width
=
40
;
}
num_counters
=
eax
.
split
.
num_counters
;
op_arch_perfmon_spec
.
num_counters
=
num_counters
;
op_arch_perfmon_spec
.
num_controls
=
num_counters
;
op_ppro_spec
.
num_counters
=
num_counters
;
op_ppro_spec
.
num_controls
=
num_counters
;
}
struct
op_x86_model_spec
op_arch_perfmon_spec
=
{
/* num_counters/num_controls filled in at runtime */
.
fill_in_addresses
=
&
ppro_fill_in_addresses
,
/* user space does the cpuid check for available events */
.
setup_ctrs
=
&
ppro_setup_ctrs
,
.
check_ctrs
=
&
ppro_check_ctrs
,
.
start
=
&
ppro_start
,
...
...
arch/x86/oprofile/op_x86_model.h
View file @
5a289395
...
...
@@ -34,8 +34,8 @@ struct pt_regs;
struct
op_x86_model_spec
{
int
(
*
init
)(
struct
oprofile_operations
*
ops
);
void
(
*
exit
)(
void
);
unsigned
int
const
num_counters
;
unsigned
int
const
num_controls
;
unsigned
int
num_counters
;
unsigned
int
num_controls
;
void
(
*
fill_in_addresses
)(
struct
op_msrs
*
const
msrs
);
void
(
*
setup_ctrs
)(
struct
op_msrs
const
*
const
msrs
);
int
(
*
check_ctrs
)(
struct
pt_regs
*
const
regs
,
...
...
@@ -45,9 +45,12 @@ struct op_x86_model_spec {
void
(
*
shutdown
)(
struct
op_msrs
const
*
const
msrs
);
};
extern
struct
op_x86_model_spec
const
op_ppro_spec
;
extern
struct
op_x86_model_spec
op_ppro_spec
;
extern
struct
op_x86_model_spec
const
op_p4_spec
;
extern
struct
op_x86_model_spec
const
op_p4_ht2_spec
;
extern
struct
op_x86_model_spec
const
op_amd_spec
;
extern
struct
op_x86_model_spec
op_arch_perfmon_spec
;
extern
void
arch_perfmon_setup_counters
(
void
);
#endif
/* OP_X86_MODEL_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment