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
nexedi
linux
Commits
14d0647c
Commit
14d0647c
authored
Apr 17, 2008
by
Tony Luck
Browse files
Options
Browse Files
Download
Plain Diff
Pull virt-cpu-accounting into release branch
parents
2a467d5f
b64f34cd
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
432 additions
and
1 deletion
+432
-1
arch/ia64/Kconfig
arch/ia64/Kconfig
+11
-0
arch/ia64/ia32/elfcore32.h
arch/ia64/ia32/elfcore32.h
+13
-1
arch/ia64/kernel/asm-offsets.c
arch/ia64/kernel/asm-offsets.c
+6
-0
arch/ia64/kernel/entry.S
arch/ia64/kernel/entry.S
+65
-0
arch/ia64/kernel/fsys.S
arch/ia64/kernel/fsys.S
+26
-0
arch/ia64/kernel/head.S
arch/ia64/kernel/head.S
+20
-0
arch/ia64/kernel/ivt.S
arch/ia64/kernel/ivt.S
+69
-0
arch/ia64/kernel/minstate.h
arch/ia64/kernel/minstate.h
+14
-0
arch/ia64/kernel/time.c
arch/ia64/kernel/time.c
+78
-0
include/asm-ia64/cputime.h
include/asm-ia64/cputime.h
+104
-0
include/asm-ia64/system.h
include/asm-ia64/system.h
+12
-0
include/asm-ia64/thread_info.h
include/asm-ia64/thread_info.h
+14
-0
No files found.
arch/ia64/Kconfig
View file @
14d0647c
...
...
@@ -283,6 +283,17 @@ config FORCE_MAX_ZONEORDER
default "17" if HUGETLB_PAGE
default "11"
config VIRT_CPU_ACCOUNTING
bool "Deterministic task and CPU time accounting"
default n
help
Select this option to enable more accurate task and CPU time
accounting. This is done by reading a CPU counter on each
kernel entry and exit and on transitions within the kernel
between system, softirq and hardirq state, so there is a
small performance impact.
If in doubt, say N here.
config SMP
bool "Symmetric multi-processing support"
help
...
...
arch/ia64/ia32/elfcore32.h
View file @
14d0647c
...
...
@@ -30,7 +30,19 @@ struct elf_siginfo
int
si_errno
;
/* errno */
};
#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
/*
* Hacks are here since types between compat_timeval (= pair of s32) and
* ia64-native timeval (= pair of s64) are not compatible, at least a file
* arch/ia64/ia32/../../../fs/binfmt_elf.c will get warnings from compiler on
* use of cputime_to_timeval(), which usually an alias of jiffies_to_timeval().
*/
#define cputime_to_timeval(a,b) \
do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0)
#else
#define jiffies_to_timeval(a,b) \
do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; } while(0)
#endif
struct
elf_prstatus
{
...
...
arch/ia64/kernel/asm-offsets.c
View file @
14d0647c
...
...
@@ -39,6 +39,12 @@ void foo(void)
DEFINE
(
TI_FLAGS
,
offsetof
(
struct
thread_info
,
flags
));
DEFINE
(
TI_CPU
,
offsetof
(
struct
thread_info
,
cpu
));
DEFINE
(
TI_PRE_COUNT
,
offsetof
(
struct
thread_info
,
preempt_count
));
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
DEFINE
(
TI_AC_STAMP
,
offsetof
(
struct
thread_info
,
ac_stamp
));
DEFINE
(
TI_AC_LEAVE
,
offsetof
(
struct
thread_info
,
ac_leave
));
DEFINE
(
TI_AC_STIME
,
offsetof
(
struct
thread_info
,
ac_stime
));
DEFINE
(
TI_AC_UTIME
,
offsetof
(
struct
thread_info
,
ac_utime
));
#endif
BLANK
();
...
...
arch/ia64/kernel/entry.S
View file @
14d0647c
...
...
@@ -710,6 +710,16 @@ ENTRY(ia64_leave_syscall)
(
pUStk
)
cmp.eq.unc
p6
,
p0
=
r0
,
r0
//
p6
<-
pUStk
#endif
.
work_processed_syscall
:
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
adds
r2
=
PT
(
LOADRS
)+
16
,
r12
(
pUStk
)
mov.m
r22
=
ar
.
itc
//
fetch
time
at
leave
adds
r18
=
TI_FLAGS
+
IA64_TASK_SIZE
,
r13
;;
(
p6
)
ld4
r31
=[
r18
]
//
load
current_thread_info
()->
flags
ld8
r19
=[
r2
],
PT
(
B6
)-
PT
(
LOADRS
)
//
load
ar
.
rsc
value
for
"loadrs"
adds
r3
=
PT
(
AR_BSPSTORE
)+
16
,
r12
//
deferred
;;
#else
adds
r2
=
PT
(
LOADRS
)+
16
,
r12
adds
r3
=
PT
(
AR_BSPSTORE
)+
16
,
r12
adds
r18
=
TI_FLAGS
+
IA64_TASK_SIZE
,
r13
...
...
@@ -718,6 +728,7 @@ ENTRY(ia64_leave_syscall)
ld8
r19
=[
r2
],
PT
(
B6
)-
PT
(
LOADRS
)
//
load
ar
.
rsc
value
for
"loadrs"
nop.i
0
;;
#endif
mov
r16
=
ar
.
bsp
//
M2
get
existing
backing
store
pointer
ld8
r18
=[
r2
],
PT
(
R9
)-
PT
(
B6
)
//
load
b6
(
p6
)
and
r15
=
TIF_WORK_MASK
,
r31
//
any
work
other
than
TIF_SYSCALL_TRACE
?
...
...
@@ -737,12 +748,21 @@ ENTRY(ia64_leave_syscall)
ld8
r29
=[
r2
],
16
//
M0
|
1
load
cr
.
ipsr
ld8
r28
=[
r3
],
16
//
M0
|
1
load
cr
.
iip
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
(
pUStk
)
add
r14
=
TI_AC_LEAVE
+
IA64_TASK_SIZE
,
r13
;;
ld8
r30
=[
r2
],
16
//
M0
|
1
load
cr
.
ifs
ld8
r25
=[
r3
],
16
//
M0
|
1
load
ar
.
unat
(
pUStk
)
add
r15
=
IA64_TASK_THREAD_ON_USTACK_OFFSET
,
r13
;;
#else
mov
r22
=
r0
//
A
clear
r22
;;
ld8
r30
=[
r2
],
16
//
M0
|
1
load
cr
.
ifs
ld8
r25
=[
r3
],
16
//
M0
|
1
load
ar
.
unat
(
pUStk
)
add
r14
=
IA64_TASK_THREAD_ON_USTACK_OFFSET
,
r13
;;
#endif
ld8
r26
=[
r2
],
PT
(
B0
)-
PT
(
AR_PFS
)
//
M0
|
1
load
ar
.
pfs
(
pKStk
)
mov
r22
=
psr
//
M2
read
PSR
now
that
interrupts
are
disabled
nop
0
...
...
@@ -759,7 +779,11 @@ ENTRY(ia64_leave_syscall)
ld8.fill
r1
=[
r3
],
16
//
M0
|
1
load
r1
(
pUStk
)
mov
r17
=
1
//
A
;;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
(
pUStk
)
st1
[
r15
]=
r17
//
M2
|
3
#else
(
pUStk
)
st1
[
r14
]=
r17
//
M2
|
3
#endif
ld8.fill
r13
=[
r3
],
16
//
M0
|
1
mov
f8
=
f0
//
F
clear
f8
;;
...
...
@@ -775,12 +799,22 @@ ENTRY(ia64_leave_syscall)
shr.u
r18
=
r19
,
16
//
I0
|
1
get
byte
size
of
existing
"dirty"
partition
cover
//
B
add
current
frame
into
dirty
partition
&
set
cr
.
ifs
;;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
mov
r19
=
ar
.
bsp
//
M2
get
new
backing
store
pointer
st8
[
r14
]=
r22
//
M
save
time
at
leave
mov
f10
=
f0
//
F
clear
f10
mov
r22
=
r0
//
A
clear
r22
movl
r14
=
__kernel_syscall_via_epc
//
X
;;
#else
mov
r19
=
ar
.
bsp
//
M2
get
new
backing
store
pointer
mov
f10
=
f0
//
F
clear
f10
nop.m
0
movl
r14
=
__kernel_syscall_via_epc
//
X
;;
#endif
mov.m
ar
.
csd
=
r0
//
M2
clear
ar
.
csd
mov.m
ar
.
ccv
=
r0
//
M2
clear
ar
.
ccv
mov
b7
=
r14
//
I0
clear
b7
(
hint
with
__kernel_syscall_via_epc
)
...
...
@@ -913,10 +947,18 @@ GLOBAL_ENTRY(ia64_leave_kernel)
adds
r16
=
PT
(
CR_IPSR
)+
16
,
r12
adds
r17
=
PT
(
CR_IIP
)+
16
,
r12
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
.
pred.rel.mutex
pUStk
,
pKStk
(
pKStk
)
mov
r22
=
psr
//
M2
read
PSR
now
that
interrupts
are
disabled
(
pUStk
)
mov.m
r22
=
ar
.
itc
//
M
fetch
time
at
leave
nop.i
0
;;
#else
(
pKStk
)
mov
r22
=
psr
//
M2
read
PSR
now
that
interrupts
are
disabled
nop.i
0
nop.i
0
;;
#endif
ld8
r29
=[
r16
],
16
//
load
cr
.
ipsr
ld8
r28
=[
r17
],
16
//
load
cr
.
iip
;;
...
...
@@ -938,15 +980,37 @@ GLOBAL_ENTRY(ia64_leave_kernel)
;;
ld8.fill
r12
=[
r16
],
16
ld8.fill
r13
=[
r17
],
16
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
(
pUStk
)
adds
r3
=
TI_AC_LEAVE
+
IA64_TASK_SIZE
,
r18
#else
(
pUStk
)
adds
r18
=
IA64_TASK_THREAD_ON_USTACK_OFFSET
,
r18
#endif
;;
ld8
r20
=[
r16
],
16
//
ar
.
fpsr
ld8.fill
r15
=[
r17
],
16
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
(
pUStk
)
adds
r18
=
IA64_TASK_THREAD_ON_USTACK_OFFSET
,
r18
//
deferred
#endif
;;
ld8.fill
r14
=[
r16
],
16
ld8.fill
r2
=[
r17
]
(
pUStk
)
mov
r17
=
1
;;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
//
mmi_
:
ld8
st1
shr
;; mmi_ : st8 st1 shr;;
//
mib
:
mov
add
br
->
mib
:
ld8
add
br
//
bbb_
:
br
nop
cover
;; mbb_ : mov br cover;;
//
//
no
one
require
bsp
in
r16
if
(
pKStk
)
branch
is
selected
.
(
pUStk
)
st8
[
r3
]=
r22
//
save
time
at
leave
(
pUStk
)
st1
[
r18
]=
r17
//
restore
current
->
thread
.
on_ustack
shr.u
r18
=
r19
,
16
//
get
byte
size
of
existing
"dirty"
partition
;;
ld8.fill
r3
=[
r16
]
//
deferred
LOAD_PHYS_STACK_REG_SIZE
(
r17
)
(
pKStk
)
br.cond.dpnt
skip_rbs_switch
mov
r16
=
ar
.
bsp
//
get
existing
backing
store
pointer
#else
ld8.fill
r3
=[
r16
]
(
pUStk
)
st1
[
r18
]=
r17
//
restore
current
->
thread
.
on_ustack
shr.u
r18
=
r19
,
16
//
get
byte
size
of
existing
"dirty"
partition
...
...
@@ -954,6 +1018,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
mov
r16
=
ar
.
bsp
//
get
existing
backing
store
pointer
LOAD_PHYS_STACK_REG_SIZE
(
r17
)
(
pKStk
)
br.cond.dpnt
skip_rbs_switch
#endif
/
*
*
Restore
user
backing
store
.
...
...
arch/ia64/kernel/fsys.S
View file @
14d0647c
...
...
@@ -656,7 +656,11 @@ GLOBAL_ENTRY(fsys_bubble_down)
nop.i
0
;;
mov
ar
.
rsc
=
0
//
M2
set
enforced
lazy
mode
,
pl
0
,
LE
,
loadrs
=
0
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
mov.m
r30
=
ar
.
itc
//
M
get
cycle
for
accounting
#else
nop.m
0
#endif
nop.i
0
;;
mov
r23
=
ar
.
bspstore
//
M2
(
12
cyc
)
save
ar
.
bspstore
...
...
@@ -678,6 +682,28 @@ GLOBAL_ENTRY(fsys_bubble_down)
cmp.ne
pKStk
,
pUStk
=
r0
,
r0
//
A
set
pKStk
<-
0
,
pUStk
<-
1
br.call.sptk.many
b7
=
ia64_syscall_setup
//
B
;;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
//
mov
.
m
r30
=
ar
.
itc
is
called
in
advance
add
r16
=
TI_AC_STAMP
+
IA64_TASK_SIZE
,
r2
add
r17
=
TI_AC_LEAVE
+
IA64_TASK_SIZE
,
r2
;;
ld8
r18
=[
r16
],
TI_AC_STIME
-
TI_AC_STAMP
//
time
at
last
check
in
kernel
ld8
r19
=[
r17
],
TI_AC_UTIME
-
TI_AC_LEAVE
//
time
at
leave
kernel
;;
ld8
r20
=[
r16
],
TI_AC_STAMP
-
TI_AC_STIME
//
cumulated
stime
ld8
r21
=[
r17
]
//
cumulated
utime
sub
r22
=
r19
,
r18
//
stime
before
leave
kernel
;;
st8
[
r16
]=
r30
,
TI_AC_STIME
-
TI_AC_STAMP
//
update
stamp
sub
r18
=
r30
,
r19
//
elapsed
time
in
user
mode
;;
add
r20
=
r20
,
r22
//
sum
stime
add
r21
=
r21
,
r18
//
sum
utime
;;
st8
[
r16
]=
r20
//
update
stime
st8
[
r17
]=
r21
//
update
utime
;;
#endif
mov
ar
.
rsc
=
0x3
//
M2
set
eager
mode
,
pl
0
,
LE
,
loadrs
=
0
mov
rp
=
r14
//
I0
set
the
real
return
addr
and
r3
=
_TIF_SYSCALL_TRACEAUDIT
,
r3
//
A
...
...
arch/ia64/kernel/head.S
View file @
14d0647c
...
...
@@ -1002,6 +1002,26 @@ GLOBAL_ENTRY(sched_clock)
br.ret.sptk.many
rp
END
(
sched_clock
)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
GLOBAL_ENTRY
(
cycle_to_cputime
)
alloc
r16
=
ar
.
pfs
,
1
,
0
,
0
,
0
addl
r8
=
THIS_CPU
(
cpu_info
)
+
IA64_CPUINFO_NSEC_PER_CYC_OFFSET
,
r0
;;
ldf8
f8
=[
r8
]
;;
setf.sig
f9
=
r32
;;
xmpy.lu
f10
=
f9
,
f8
//
calculate
low
64
bits
of
128
-
bit
product
(
4
cyc
)
xmpy.hu
f11
=
f9
,
f8
//
calculate
high
64
bits
of
128
-
bit
product
;;
getf.sig
r8
=
f10
//
(
5
cyc
)
getf.sig
r9
=
f11
;;
shrp
r8
=
r9
,
r8
,
IA64_NSEC_PER_CYC_SHIFT
br.ret.sptk.many
rp
END
(
cycle_to_cputime
)
#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
GLOBAL_ENTRY
(
start_kernel_thread
)
.
prologue
.
save
rp
,
r0
//
this
is
the
end
of
the
call
-
chain
...
...
arch/ia64/kernel/ivt.S
View file @
14d0647c
...
...
@@ -805,8 +805,13 @@ ENTRY(break_fault)
(
p8
)
adds
r28
=
16
,
r28
//
A
switch
cr
.
iip
to
next
bundle
(
p9
)
adds
r8
=
1
,
r8
//
A
increment
ei
to
next
slot
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
;;
mov
b6
=
r30
//
I0
setup
syscall
handler
branch
reg
early
#else
nop.i
0
;;
#endif
mov.m
r25
=
ar
.
unat
//
M2
(
5
cyc
)
dep
r29
=
r8
,
r29
,
41
,
2
//
I0
insert
new
ei
into
cr
.
ipsr
...
...
@@ -817,7 +822,11 @@ ENTRY(break_fault)
//
///////////////////////////////////////////////////////////////////////
st1
[
r16
]=
r0
//
M2
|
3
clear
current
->
thread
.
on_ustack
flag
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
mov.m
r30
=
ar
.
itc
//
M
get
cycle
for
accounting
#else
mov
b6
=
r30
//
I0
setup
syscall
handler
branch
reg
early
#endif
cmp.eq
pKStk
,
pUStk
=
r0
,
r17
//
A
were
we
on
kernel
stacks
already
?
and
r9
=
_TIF_SYSCALL_TRACEAUDIT
,
r9
//
A
mask
trace
or
audit
...
...
@@ -829,6 +838,30 @@ ENTRY(break_fault)
cmp.eq
p14
,
p0
=
r9
,
r0
//
A
are
syscalls
being
traced
/
audited
?
br.call.sptk.many
b7
=
ia64_syscall_setup
//
B
1
:
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
//
mov
.
m
r30
=
ar
.
itc
is
called
in
advance
,
and
r13
is
current
add
r16
=
TI_AC_STAMP
+
IA64_TASK_SIZE
,
r13
//
A
add
r17
=
TI_AC_LEAVE
+
IA64_TASK_SIZE
,
r13
//
A
(
pKStk
)
br.cond.spnt
.
skip_accounting
//
B
unlikely
skip
;;
ld8
r18
=[
r16
],
TI_AC_STIME
-
TI_AC_STAMP
//
M
get
last
stamp
ld8
r19
=[
r17
],
TI_AC_UTIME
-
TI_AC_LEAVE
//
M
time
at
leave
;;
ld8
r20
=[
r16
],
TI_AC_STAMP
-
TI_AC_STIME
//
M
cumulated
stime
ld8
r21
=[
r17
]
//
M
cumulated
utime
sub
r22
=
r19
,
r18
//
A
stime
before
leave
;;
st8
[
r16
]=
r30
,
TI_AC_STIME
-
TI_AC_STAMP
//
M
update
stamp
sub
r18
=
r30
,
r19
//
A
elapsed
time
in
user
;;
add
r20
=
r20
,
r22
//
A
sum
stime
add
r21
=
r21
,
r18
//
A
sum
utime
;;
st8
[
r16
]=
r20
//
M
update
stime
st8
[
r17
]=
r21
//
M
update
utime
;;
.
skip_accounting
:
#endif
mov
ar
.
rsc
=
0x3
//
M2
set
eager
mode
,
pl
0
,
LE
,
loadrs
=
0
nop
0
bsw.
1
//
B
(
6
cyc
)
regs
are
saved
,
switch
to
bank
1
...
...
@@ -928,6 +961,7 @@ END(interrupt)
*
-
r27
:
saved
ar
.
rsc
*
-
r28
:
saved
cr
.
iip
*
-
r29
:
saved
cr
.
ipsr
*
-
r30
:
ar
.
itc
for
accounting
(
don
't touch)
*
-
r31
:
saved
pr
*
-
b0
:
original
contents
(
to
be
saved
)
*
On
exit
:
...
...
@@ -1090,6 +1124,41 @@ END(dispatch_illegal_op_fault)
DBG_FAULT
(16)
FAULT
(16)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
/
*
*
There
is
no
particular
reason
for
this
code
to
be
here
,
other
than
*
that
there
happens
to
be
space
here
that
would
go
unused
otherwise
.
*
If
this
fault
ever
gets
"unreserved"
,
simply
moved
the
following
*
code
to
a
more
suitable
spot
...
*
*
account_sys_enter
is
called
from
SAVE_MIN
*
macros
if
accounting
is
*
enabled
and
if
the
macro
is
entered
from
user
mode
.
*/
ENTRY
(
account_sys_enter
)
//
mov
.
m
r20
=
ar
.
itc
is
called
in
advance
,
and
r13
is
current
add
r16
=
TI_AC_STAMP
+
IA64_TASK_SIZE
,
r13
add
r17
=
TI_AC_LEAVE
+
IA64_TASK_SIZE
,
r13
;;
ld8
r18
=[
r16
],
TI_AC_STIME
-
TI_AC_STAMP
//
time
at
last
check
in
kernel
ld8
r19
=[
r17
],
TI_AC_UTIME
-
TI_AC_LEAVE
//
time
at
left
from
kernel
;;
ld8
r23
=[
r16
],
TI_AC_STAMP
-
TI_AC_STIME
//
cumulated
stime
ld8
r21
=[
r17
]
//
cumulated
utime
sub
r22
=
r19
,
r18
//
stime
before
leave
kernel
;;
st8
[
r16
]=
r20
,
TI_AC_STIME
-
TI_AC_STAMP
//
update
stamp
sub
r18
=
r20
,
r19
//
elapsed
time
in
user
mode
;;
add
r23
=
r23
,
r22
//
sum
stime
add
r21
=
r21
,
r18
//
sum
utime
;;
st8
[
r16
]=
r23
//
update
stime
st8
[
r17
]=
r21
//
update
utime
;;
br.ret.sptk.many
rp
END
(
account_sys_enter
)
#endif
.
org
ia64_ivt
+
0x4400
/////////////////////////////////////////////////////////////////////////////////////////
//
0
x4400
Entry
17
(
size
64
bundles
)
Reserved
...
...
arch/ia64/kernel/minstate.h
View file @
14d0647c
...
...
@@ -3,6 +3,18 @@
#include "entry.h"
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
/* read ar.itc in advance, and use it before leaving bank 0 */
#define ACCOUNT_GET_STAMP \
(pUStk) mov.m r20=ar.itc;
#define ACCOUNT_SYS_ENTER \
(pUStk) br.call.spnt rp=account_sys_enter \
;;
#else
#define ACCOUNT_GET_STAMP
#define ACCOUNT_SYS_ENTER
#endif
/*
* DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
* the minimum state necessary that allows us to turn psr.ic back
...
...
@@ -122,11 +134,13 @@
;; \
.mem.offset 0,0; st8.spill [r16]=r2,16; \
.mem.offset 8,0; st8.spill [r17]=r3,16; \
ACCOUNT_GET_STAMP \
adds r2=IA64_PT_REGS_R16_OFFSET,r1; \
;; \
EXTRA; \
movl r1=__gp;
/* establish kernel global pointer */
\
;; \
ACCOUNT_SYS_ENTER \
bsw.1;
/* switch back to bank 1 (must be last in insn group) */
\
;;
...
...
arch/ia64/kernel/time.c
View file @
14d0647c
...
...
@@ -59,6 +59,84 @@ static struct clocksource clocksource_itc = {
};
static
struct
clocksource
*
itc_clocksource
;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
#include <linux/kernel_stat.h>
extern
cputime_t
cycle_to_cputime
(
u64
cyc
);
/*
* Called from the context switch with interrupts disabled, to charge all
* accumulated times to the current process, and to prepare accounting on
* the next process.
*/
void
ia64_account_on_switch
(
struct
task_struct
*
prev
,
struct
task_struct
*
next
)
{
struct
thread_info
*
pi
=
task_thread_info
(
prev
);
struct
thread_info
*
ni
=
task_thread_info
(
next
);
cputime_t
delta_stime
,
delta_utime
;
__u64
now
;
now
=
ia64_get_itc
();
delta_stime
=
cycle_to_cputime
(
pi
->
ac_stime
+
(
now
-
pi
->
ac_stamp
));
account_system_time
(
prev
,
0
,
delta_stime
);
account_system_time_scaled
(
prev
,
delta_stime
);
if
(
pi
->
ac_utime
)
{
delta_utime
=
cycle_to_cputime
(
pi
->
ac_utime
);
account_user_time
(
prev
,
delta_utime
);
account_user_time_scaled
(
prev
,
delta_utime
);
}
pi
->
ac_stamp
=
ni
->
ac_stamp
=
now
;
ni
->
ac_stime
=
ni
->
ac_utime
=
0
;
}
/*
* Account time for a transition between system, hard irq or soft irq state.
* Note that this function is called with interrupts enabled.
*/
void
account_system_vtime
(
struct
task_struct
*
tsk
)
{
struct
thread_info
*
ti
=
task_thread_info
(
tsk
);
unsigned
long
flags
;
cputime_t
delta_stime
;
__u64
now
;
local_irq_save
(
flags
);
now
=
ia64_get_itc
();
delta_stime
=
cycle_to_cputime
(
ti
->
ac_stime
+
(
now
-
ti
->
ac_stamp
));
account_system_time
(
tsk
,
0
,
delta_stime
);
account_system_time_scaled
(
tsk
,
delta_stime
);
ti
->
ac_stime
=
0
;
ti
->
ac_stamp
=
now
;
local_irq_restore
(
flags
);
}
/*
* Called from the timer interrupt handler to charge accumulated user time
* to the current process. Must be called with interrupts disabled.
*/
void
account_process_tick
(
struct
task_struct
*
p
,
int
user_tick
)
{
struct
thread_info
*
ti
=
task_thread_info
(
p
);
cputime_t
delta_utime
;
if
(
ti
->
ac_utime
)
{
delta_utime
=
cycle_to_cputime
(
ti
->
ac_utime
);
account_user_time
(
p
,
delta_utime
);
account_user_time_scaled
(
p
,
delta_utime
);
ti
->
ac_utime
=
0
;
}
}
#endif
/* CONFIG_VIRT_CPU_ACCOUNTING */
static
irqreturn_t
timer_interrupt
(
int
irq
,
void
*
dev_id
)
{
...
...
include/asm-ia64/cputime.h
View file @
14d0647c
/*
* include/asm-ia64/cputime.h:
* Definitions for measuring cputime on ia64 machines.
*
* Based on <asm-powerpc/cputime.h>.
*
* Copyright (C) 2007 FUJITSU LIMITED
* Copyright (C) 2007 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in nsec.
* Otherwise we measure cpu time in jiffies using the generic definitions.
*/
#ifndef __IA64_CPUTIME_H
#define __IA64_CPUTIME_H
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
#include <asm-generic/cputime.h>
#else
#include <linux/time.h>
#include <linux/jiffies.h>
#include <asm/processor.h>
typedef
u64
cputime_t
;
typedef
u64
cputime64_t
;
#define cputime_zero ((cputime_t)0)
#define cputime_max ((~((cputime_t)0) >> 1) - 1)
#define cputime_add(__a, __b) ((__a) + (__b))
#define cputime_sub(__a, __b) ((__a) - (__b))
#define cputime_div(__a, __n) ((__a) / (__n))
#define cputime_halve(__a) ((__a) >> 1)
#define cputime_eq(__a, __b) ((__a) == (__b))
#define cputime_gt(__a, __b) ((__a) > (__b))
#define cputime_ge(__a, __b) ((__a) >= (__b))
#define cputime_lt(__a, __b) ((__a) < (__b))
#define cputime_le(__a, __b) ((__a) <= (__b))
#define cputime64_zero ((cputime64_t)0)
#define cputime64_add(__a, __b) ((__a) + (__b))
#define cputime64_sub(__a, __b) ((__a) - (__b))
#define cputime_to_cputime64(__ct) (__ct)
/*
* Convert cputime <-> jiffies (HZ)
*/
#define cputime_to_jiffies(__ct) ((__ct) / (NSEC_PER_SEC / HZ))
#define jiffies_to_cputime(__jif) ((__jif) * (NSEC_PER_SEC / HZ))
#define cputime64_to_jiffies64(__ct) ((__ct) / (NSEC_PER_SEC / HZ))
#define jiffies64_to_cputime64(__jif) ((__jif) * (NSEC_PER_SEC / HZ))
/*
* Convert cputime <-> milliseconds
*/
#define cputime_to_msecs(__ct) ((__ct) / NSEC_PER_MSEC)
#define msecs_to_cputime(__msecs) ((__msecs) * NSEC_PER_MSEC)
/*
* Convert cputime <-> seconds
*/
#define cputime_to_secs(__ct) ((__ct) / NSEC_PER_SEC)
#define secs_to_cputime(__secs) ((__secs) * NSEC_PER_SEC)
/*
* Convert cputime <-> timespec (nsec)
*/
static
inline
cputime_t
timespec_to_cputime
(
const
struct
timespec
*
val
)
{
cputime_t
ret
=
val
->
tv_sec
*
NSEC_PER_SEC
;
return
(
ret
+
val
->
tv_nsec
);
}
static
inline
void
cputime_to_timespec
(
const
cputime_t
ct
,
struct
timespec
*
val
)
{
val
->
tv_sec
=
ct
/
NSEC_PER_SEC
;
val
->
tv_nsec
=
ct
%
NSEC_PER_SEC
;
}
/*
* Convert cputime <-> timeval (msec)
*/
static
inline
cputime_t
timeval_to_cputime
(
struct
timeval
*
val
)
{
cputime_t
ret
=
val
->
tv_sec
*
NSEC_PER_SEC
;
return
(
ret
+
val
->
tv_usec
*
NSEC_PER_USEC
);
}
static
inline
void
cputime_to_timeval
(
const
cputime_t
ct
,
struct
timeval
*
val
)
{
val
->
tv_sec
=
ct
/
NSEC_PER_SEC
;
val
->
tv_usec
=
(
ct
%
NSEC_PER_SEC
)
/
NSEC_PER_USEC
;
}
/*
* Convert cputime <-> clock (USER_HZ)
*/
#define cputime_to_clock_t(__ct) ((__ct) / (NSEC_PER_SEC / USER_HZ))
#define clock_t_to_cputime(__x) ((__x) * (NSEC_PER_SEC / USER_HZ))
/*
* Convert cputime64 to clock.
*/
#define cputime64_to_clock_t(__ct) cputime_to_clock_t((cputime_t)__ct)
#endif
/* CONFIG_VIRT_CPU_ACCOUNTING */
#endif
/* __IA64_CPUTIME_H */
include/asm-ia64/system.h
View file @
14d0647c
...
...
@@ -210,6 +210,13 @@ struct task_struct;
extern
void
ia64_save_extra
(
struct
task_struct
*
task
);
extern
void
ia64_load_extra
(
struct
task_struct
*
task
);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
extern
void
ia64_account_on_switch
(
struct
task_struct
*
prev
,
struct
task_struct
*
next
);
# define IA64_ACCOUNT_ON_SWITCH(p,n) ia64_account_on_switch(p,n)
#else
# define IA64_ACCOUNT_ON_SWITCH(p,n)
#endif
#ifdef CONFIG_PERFMON
DECLARE_PER_CPU
(
unsigned
long
,
pfm_syst_info
);
# define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1)
...
...
@@ -222,6 +229,7 @@ extern void ia64_load_extra (struct task_struct *task);
|| IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE())
#define __switch_to(prev,next,last) do { \
IA64_ACCOUNT_ON_SWITCH(prev, next); \
if (IA64_HAS_EXTRA_STATE(prev)) \
ia64_save_extra(prev); \
if (IA64_HAS_EXTRA_STATE(next)) \
...
...
@@ -266,6 +274,10 @@ void cpu_idle_wait(void);
void
default_idle
(
void
);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
extern
void
account_system_vtime
(
struct
task_struct
*
);
#endif
#endif
/* __KERNEL__ */
#endif
/* __ASSEMBLY__ */
...
...
include/asm-ia64/thread_info.h
View file @
14d0647c
...
...
@@ -31,6 +31,12 @@ struct thread_info {
mm_segment_t
addr_limit
;
/* user-level address space limit */
int
preempt_count
;
/* 0=premptable, <0=BUG; will also serve as bh-counter */
struct
restart_block
restart_block
;
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
__u64
ac_stamp
;
__u64
ac_leave
;
__u64
ac_stime
;
__u64
ac_utime
;
#endif
};
#define THREAD_SIZE KERNEL_STACK_SIZE
...
...
@@ -62,9 +68,17 @@ struct thread_info {
#define task_stack_page(tsk) ((void *)(tsk))
#define __HAVE_THREAD_FUNCTIONS
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
#define setup_thread_stack(p, org) \
*task_thread_info(p) = *task_thread_info(org); \
task_thread_info(p)->ac_stime = 0; \
task_thread_info(p)->ac_utime = 0; \
task_thread_info(p)->task = (p);
#else
#define setup_thread_stack(p, org) \
*task_thread_info(p) = *task_thread_info(org); \
task_thread_info(p)->task = (p);
#endif
#define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET)
#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
...
...
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