Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8df341cf
Commit
8df341cf
authored
Mar 17, 2011
by
Ingo Molnar
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'core' of
git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile
into perf/urgent
parents
eb4316dd
ec6b426c
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1558 additions
and
13 deletions
+1558
-13
arch/s390/oprofile/Makefile
arch/s390/oprofile/Makefile
+1
-1
arch/s390/oprofile/hwsampler.c
arch/s390/oprofile/hwsampler.c
+1256
-0
arch/s390/oprofile/hwsampler.h
arch/s390/oprofile/hwsampler.h
+113
-0
arch/s390/oprofile/init.c
arch/s390/oprofile/init.c
+162
-3
drivers/oprofile/cpu_buffer.c
drivers/oprofile/cpu_buffer.c
+17
-7
drivers/oprofile/timer_int.c
drivers/oprofile/timer_int.c
+2
-2
include/linux/oprofile.h
include/linux/oprofile.h
+7
-0
No files found.
arch/s390/oprofile/Makefile
View file @
8df341cf
...
...
@@ -6,4 +6,4 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofilefs.o oprofile_stats.o
\
timer_int.o
)
oprofile-y
:=
$(DRIVER_OBJS)
init.o backtrace
.o
oprofile-y
:=
$(DRIVER_OBJS)
init.o backtrace.o hwsampler
.o
arch/s390/oprofile/hwsampler.c
0 → 100644
View file @
8df341cf
This diff is collapsed.
Click to expand it.
arch/s390/oprofile/hwsampler.h
0 → 100644
View file @
8df341cf
/*
* CPUMF HW sampler functions and internal structures
*
* Copyright IBM Corp. 2010
* Author(s): Heinz Graalfs <graalfs@de.ibm.com>
*/
#ifndef HWSAMPLER_H_
#define HWSAMPLER_H_
#include <linux/workqueue.h>
struct
hws_qsi_info_block
/* QUERY SAMPLING information block */
{
/* Bit(s) */
unsigned
int
b0_13
:
14
;
/* 0-13: zeros */
unsigned
int
as
:
1
;
/* 14: sampling authorisation control*/
unsigned
int
b15_21
:
7
;
/* 15-21: zeros */
unsigned
int
es
:
1
;
/* 22: sampling enable control */
unsigned
int
b23_29
:
7
;
/* 23-29: zeros */
unsigned
int
cs
:
1
;
/* 30: sampling activation control */
unsigned
int
:
1
;
/* 31: reserved */
unsigned
int
bsdes
:
16
;
/* 4-5: size of sampling entry */
unsigned
int
:
16
;
/* 6-7: reserved */
unsigned
long
min_sampl_rate
;
/* 8-15: minimum sampling interval */
unsigned
long
max_sampl_rate
;
/* 16-23: maximum sampling interval*/
unsigned
long
tear
;
/* 24-31: TEAR contents */
unsigned
long
dear
;
/* 32-39: DEAR contents */
unsigned
int
rsvrd0
;
/* 40-43: reserved */
unsigned
int
cpu_speed
;
/* 44-47: CPU speed */
unsigned
long
long
rsvrd1
;
/* 48-55: reserved */
unsigned
long
long
rsvrd2
;
/* 56-63: reserved */
};
struct
hws_ssctl_request_block
/* SET SAMPLING CONTROLS req block */
{
/* bytes 0 - 7 Bit(s) */
unsigned
int
s
:
1
;
/* 0: maximum buffer indicator */
unsigned
int
h
:
1
;
/* 1: part. level reserved for VM use*/
unsigned
long
b2_53
:
52
;
/* 2-53: zeros */
unsigned
int
es
:
1
;
/* 54: sampling enable control */
unsigned
int
b55_61
:
7
;
/* 55-61: - zeros */
unsigned
int
cs
:
1
;
/* 62: sampling activation control */
unsigned
int
b63
:
1
;
/* 63: zero */
unsigned
long
interval
;
/* 8-15: sampling interval */
unsigned
long
tear
;
/* 16-23: TEAR contents */
unsigned
long
dear
;
/* 24-31: DEAR contents */
/* 32-63: */
unsigned
long
rsvrd1
;
/* reserved */
unsigned
long
rsvrd2
;
/* reserved */
unsigned
long
rsvrd3
;
/* reserved */
unsigned
long
rsvrd4
;
/* reserved */
};
struct
hws_cpu_buffer
{
unsigned
long
first_sdbt
;
/* @ of 1st SDB-Table for this CP*/
unsigned
long
worker_entry
;
unsigned
long
sample_overflow
;
/* taken from SDB ... */
struct
hws_qsi_info_block
qsi
;
struct
hws_ssctl_request_block
ssctl
;
struct
work_struct
worker
;
atomic_t
ext_params
;
unsigned
long
req_alert
;
unsigned
long
loss_of_sample_data
;
unsigned
long
invalid_entry_address
;
unsigned
long
incorrect_sdbt_entry
;
unsigned
long
sample_auth_change_alert
;
unsigned
int
finish
:
1
;
unsigned
int
oom
:
1
;
unsigned
int
stop_mode
:
1
;
};
struct
hws_data_entry
{
unsigned
int
def
:
16
;
/* 0-15 Data Entry Format */
unsigned
int
R
:
4
;
/* 16-19 reserved */
unsigned
int
U
:
4
;
/* 20-23 Number of unique instruct. */
unsigned
int
z
:
2
;
/* zeros */
unsigned
int
T
:
1
;
/* 26 PSW DAT mode */
unsigned
int
W
:
1
;
/* 27 PSW wait state */
unsigned
int
P
:
1
;
/* 28 PSW Problem state */
unsigned
int
AS
:
2
;
/* 29-30 PSW address-space control */
unsigned
int
I
:
1
;
/* 31 entry valid or invalid */
unsigned
int
:
16
;
unsigned
int
prim_asn
:
16
;
/* primary ASN */
unsigned
long
long
ia
;
/* Instruction Address */
unsigned
long
long
lpp
;
/* Logical-Partition Program Param. */
unsigned
long
long
vpp
;
/* Virtual-Machine Program Param. */
};
struct
hws_trailer_entry
{
unsigned
int
f
:
1
;
/* 0 - Block Full Indicator */
unsigned
int
a
:
1
;
/* 1 - Alert request control */
unsigned
long
:
62
;
/* 2 - 63: Reserved */
unsigned
long
overflow
;
/* 64 - sample Overflow count */
unsigned
long
timestamp
;
/* 16 - time-stamp */
unsigned
long
timestamp1
;
/* */
unsigned
long
reserved1
;
/* 32 -Reserved */
unsigned
long
reserved2
;
/* */
unsigned
long
progusage1
;
/* 48 - reserved for programming use */
unsigned
long
progusage2
;
/* */
};
int
hwsampler_setup
(
void
);
int
hwsampler_shutdown
(
void
);
int
hwsampler_allocate
(
unsigned
long
sdbt
,
unsigned
long
sdb
);
int
hwsampler_deallocate
(
void
);
long
hwsampler_query_min_interval
(
void
);
long
hwsampler_query_max_interval
(
void
);
int
hwsampler_start_all
(
unsigned
long
interval
);
int
hwsampler_stop_all
(
void
);
int
hwsampler_deactivate
(
unsigned
int
cpu
);
int
hwsampler_activate
(
unsigned
int
cpu
);
unsigned
long
hwsampler_get_sample_overflow_count
(
unsigned
int
cpu
);
#endif
/*HWSAMPLER_H_*/
arch/s390/oprofile/init.c
View file @
8df341cf
...
...
@@ -4,23 +4,182 @@
* S390 Version
* Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Thomas Spatzier (tspat@de.ibm.com)
* Author(s): Mahesh Salgaonkar (mahesh@linux.vnet.ibm.com)
* Author(s): Heinz Graalfs (graalfs@linux.vnet.ibm.com)
*
* @remark Copyright 2002 OProfile authors
* @remark Copyright 2002
-2011
OProfile authors
*/
#include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/oprofile.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include "../../../drivers/oprofile/oprof.h"
#include "hwsampler.h"
#define DEFAULT_INTERVAL 4096
#define DEFAULT_SDBT_BLOCKS 1
#define DEFAULT_SDB_BLOCKS 511
static
unsigned
long
oprofile_hw_interval
=
DEFAULT_INTERVAL
;
static
unsigned
long
oprofile_min_interval
;
static
unsigned
long
oprofile_max_interval
;
static
unsigned
long
oprofile_sdbt_blocks
=
DEFAULT_SDBT_BLOCKS
;
static
unsigned
long
oprofile_sdb_blocks
=
DEFAULT_SDB_BLOCKS
;
static
int
hwsampler_file
;
static
int
hwsampler_running
;
/* start_mutex must be held to change */
static
struct
oprofile_operations
timer_ops
;
extern
void
s390_backtrace
(
struct
pt_regs
*
const
regs
,
unsigned
int
depth
);
int
__init
oprofile_arch_init
(
struct
oprofile_operations
*
ops
)
static
int
oprofile_hwsampler_start
(
void
)
{
int
retval
;
hwsampler_running
=
hwsampler_file
;
if
(
!
hwsampler_running
)
return
timer_ops
.
start
();
retval
=
hwsampler_allocate
(
oprofile_sdbt_blocks
,
oprofile_sdb_blocks
);
if
(
retval
)
return
retval
;
retval
=
hwsampler_start_all
(
oprofile_hw_interval
);
if
(
retval
)
hwsampler_deallocate
();
return
retval
;
}
static
void
oprofile_hwsampler_stop
(
void
)
{
if
(
!
hwsampler_running
)
{
timer_ops
.
stop
();
return
;
}
hwsampler_stop_all
();
hwsampler_deallocate
();
return
;
}
static
ssize_t
hwsampler_read
(
struct
file
*
file
,
char
__user
*
buf
,
size_t
count
,
loff_t
*
offset
)
{
return
oprofilefs_ulong_to_user
(
hwsampler_file
,
buf
,
count
,
offset
);
}
static
ssize_t
hwsampler_write
(
struct
file
*
file
,
char
const
__user
*
buf
,
size_t
count
,
loff_t
*
offset
)
{
unsigned
long
val
;
int
retval
;
if
(
*
offset
)
return
-
EINVAL
;
retval
=
oprofilefs_ulong_from_user
(
&
val
,
buf
,
count
);
if
(
retval
)
return
retval
;
if
(
oprofile_started
)
/*
* save to do without locking as we set
* hwsampler_running in start() when start_mutex is
* held
*/
return
-
EBUSY
;
hwsampler_file
=
val
;
return
count
;
}
static
const
struct
file_operations
hwsampler_fops
=
{
.
read
=
hwsampler_read
,
.
write
=
hwsampler_write
,
};
static
int
oprofile_create_hwsampling_files
(
struct
super_block
*
sb
,
struct
dentry
*
root
)
{
struct
dentry
*
hw_dir
;
/* reinitialize default values */
hwsampler_file
=
1
;
hw_dir
=
oprofilefs_mkdir
(
sb
,
root
,
"hwsampling"
);
if
(
!
hw_dir
)
return
-
EINVAL
;
oprofilefs_create_file
(
sb
,
hw_dir
,
"hwsampler"
,
&
hwsampler_fops
);
oprofilefs_create_ulong
(
sb
,
hw_dir
,
"hw_interval"
,
&
oprofile_hw_interval
);
oprofilefs_create_ro_ulong
(
sb
,
hw_dir
,
"hw_min_interval"
,
&
oprofile_min_interval
);
oprofilefs_create_ro_ulong
(
sb
,
hw_dir
,
"hw_max_interval"
,
&
oprofile_max_interval
);
oprofilefs_create_ulong
(
sb
,
hw_dir
,
"hw_sdbt_blocks"
,
&
oprofile_sdbt_blocks
);
return
0
;
}
static
int
oprofile_hwsampler_init
(
struct
oprofile_operations
*
ops
)
{
if
(
hwsampler_setup
())
return
-
ENODEV
;
/*
* create hwsampler files only if hwsampler_setup() succeeds.
*/
oprofile_min_interval
=
hwsampler_query_min_interval
();
if
(
oprofile_min_interval
<
0
)
{
oprofile_min_interval
=
0
;
return
-
ENODEV
;
}
oprofile_max_interval
=
hwsampler_query_max_interval
();
if
(
oprofile_max_interval
<
0
)
{
oprofile_max_interval
=
0
;
return
-
ENODEV
;
}
if
(
oprofile_timer_init
(
ops
))
return
-
ENODEV
;
printk
(
KERN_INFO
"oprofile: using hardware sampling
\n
"
);
memcpy
(
&
timer_ops
,
ops
,
sizeof
(
timer_ops
));
ops
->
start
=
oprofile_hwsampler_start
;
ops
->
stop
=
oprofile_hwsampler_stop
;
ops
->
create_files
=
oprofile_create_hwsampling_files
;
return
0
;
}
static
void
oprofile_hwsampler_exit
(
void
)
{
oprofile_timer_exit
();
hwsampler_shutdown
();
}
int
__init
oprofile_arch_init
(
struct
oprofile_operations
*
ops
)
{
ops
->
backtrace
=
s390_backtrace
;
return
-
ENODEV
;
return
oprofile_hwsampler_init
(
ops
);
}
void
oprofile_arch_exit
(
void
)
{
oprofile_hwsampler_exit
();
}
drivers/oprofile/cpu_buffer.c
View file @
8df341cf
...
...
@@ -258,8 +258,10 @@ op_add_sample(struct oprofile_cpu_buffer *cpu_buf,
*/
static
int
log_sample
(
struct
oprofile_cpu_buffer
*
cpu_buf
,
unsigned
long
pc
,
unsigned
long
backtrace
,
int
is_kernel
,
unsigned
long
event
)
unsigned
long
backtrace
,
int
is_kernel
,
unsigned
long
event
,
struct
task_struct
*
task
)
{
struct
task_struct
*
tsk
=
task
?
task
:
current
;
cpu_buf
->
sample_received
++
;
if
(
pc
==
ESCAPE_CODE
)
{
...
...
@@ -267,7 +269,7 @@ log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc,
return
0
;
}
if
(
op_add_code
(
cpu_buf
,
backtrace
,
is_kernel
,
current
))
if
(
op_add_code
(
cpu_buf
,
backtrace
,
is_kernel
,
tsk
))
goto
fail
;
if
(
op_add_sample
(
cpu_buf
,
pc
,
event
))
...
...
@@ -292,7 +294,8 @@ static inline void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf)
static
inline
void
__oprofile_add_ext_sample
(
unsigned
long
pc
,
struct
pt_regs
*
const
regs
,
unsigned
long
event
,
int
is_kernel
)
unsigned
long
event
,
int
is_kernel
,
struct
task_struct
*
task
)
{
struct
oprofile_cpu_buffer
*
cpu_buf
=
&
__get_cpu_var
(
op_cpu_buffer
);
unsigned
long
backtrace
=
oprofile_backtrace_depth
;
...
...
@@ -301,7 +304,7 @@ __oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
* if log_sample() fail we can't backtrace since we lost the
* source of this event
*/
if
(
!
log_sample
(
cpu_buf
,
pc
,
backtrace
,
is_kernel
,
event
))
if
(
!
log_sample
(
cpu_buf
,
pc
,
backtrace
,
is_kernel
,
event
,
task
))
/* failed */
return
;
...
...
@@ -313,10 +316,17 @@ __oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
oprofile_end_trace
(
cpu_buf
);
}
void
oprofile_add_ext_hw_sample
(
unsigned
long
pc
,
struct
pt_regs
*
const
regs
,
unsigned
long
event
,
int
is_kernel
,
struct
task_struct
*
task
)
{
__oprofile_add_ext_sample
(
pc
,
regs
,
event
,
is_kernel
,
task
);
}
void
oprofile_add_ext_sample
(
unsigned
long
pc
,
struct
pt_regs
*
const
regs
,
unsigned
long
event
,
int
is_kernel
)
{
__oprofile_add_ext_sample
(
pc
,
regs
,
event
,
is_kernel
);
__oprofile_add_ext_sample
(
pc
,
regs
,
event
,
is_kernel
,
NULL
);
}
void
oprofile_add_sample
(
struct
pt_regs
*
const
regs
,
unsigned
long
event
)
...
...
@@ -332,7 +342,7 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
pc
=
ESCAPE_CODE
;
/* as this causes an early return. */
}
__oprofile_add_ext_sample
(
pc
,
regs
,
event
,
is_kernel
);
__oprofile_add_ext_sample
(
pc
,
regs
,
event
,
is_kernel
,
NULL
);
}
/*
...
...
@@ -403,7 +413,7 @@ int oprofile_write_commit(struct op_entry *entry)
void
oprofile_add_pc
(
unsigned
long
pc
,
int
is_kernel
,
unsigned
long
event
)
{
struct
oprofile_cpu_buffer
*
cpu_buf
=
&
__get_cpu_var
(
op_cpu_buffer
);
log_sample
(
cpu_buf
,
pc
,
0
,
is_kernel
,
event
);
log_sample
(
cpu_buf
,
pc
,
0
,
is_kernel
,
event
,
NULL
);
}
void
oprofile_add_trace
(
unsigned
long
pc
)
...
...
drivers/oprofile/timer_int.c
View file @
8df341cf
...
...
@@ -97,7 +97,7 @@ static struct notifier_block __refdata oprofile_cpu_notifier = {
.
notifier_call
=
oprofile_cpu_notify
,
};
int
__init
oprofile_timer_init
(
struct
oprofile_operations
*
ops
)
int
oprofile_timer_init
(
struct
oprofile_operations
*
ops
)
{
int
rc
;
...
...
@@ -113,7 +113,7 @@ int __init oprofile_timer_init(struct oprofile_operations *ops)
return
0
;
}
void
__exit
oprofile_timer_exit
(
void
)
void
oprofile_timer_exit
(
void
)
{
unregister_hotcpu_notifier
(
&
oprofile_cpu_notifier
);
}
include/linux/oprofile.h
View file @
8df341cf
...
...
@@ -106,6 +106,13 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event);
void
oprofile_add_ext_sample
(
unsigned
long
pc
,
struct
pt_regs
*
const
regs
,
unsigned
long
event
,
int
is_kernel
);
/**
* Add an hardware sample.
*/
void
oprofile_add_ext_hw_sample
(
unsigned
long
pc
,
struct
pt_regs
*
const
regs
,
unsigned
long
event
,
int
is_kernel
,
struct
task_struct
*
task
);
/* Use this instead when the PC value is not from the regs. Doesn't
* backtrace. */
void
oprofile_add_pc
(
unsigned
long
pc
,
int
is_kernel
,
unsigned
long
event
);
...
...
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