diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-02-05 07:10:33 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-02-05 07:10:33 -0500 |
commit | b2c77a57e4a0a7877e357dead7ee8acc19944f3e (patch) | |
tree | fa192b5a058711299c2a8ce2621df6c9bd8f3a99 /arch/ia64/kernel | |
parent | c3c186403c6abd32e719f005f0af950155a9e54d (diff) | |
parent | 6a61671bb2f3a1bd12cd17b8fca811a624782632 (diff) |
Merge tag 'full-dynticks-cputime-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks into sched/core
Pull full-dynticks (user-space execution is undisturbed and
receives no timer IRQs) preparation changes that convert the
cputime accounting code to be full-dynticks ready,
from Frederic Weisbecker:
"This implements the cputime accounting on full dynticks CPUs.
Typical cputime stats infrastructure relies on the timer tick and
its periodic polling on the CPU to account the amount of time
spent by the CPUs and the tasks per high level domains such as
userspace, kernelspace, guest, ...
Now we are preparing to implement full dynticks capability on
Linux for Real Time and HPC users who want full CPU isolation.
This feature requires a cputime accounting that doesn't depend
on the timer tick.
To implement it, this new cputime infrastructure plugs into
kernel/user/guest boundaries to take snapshots of cputime and
flush these to the stats when needed. This performs pretty
much like CONFIG_VIRT_CPU_ACCOUNTING except that context location
and cputime snaphots are synchronized between write and read
side such that the latter can safely retrieve the pending tickless
cputime of a task and add it to its latest cputime snapshot to
return the correct result to the user."
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r-- | arch/ia64/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/entry.S | 16 | ||||
-rw-r--r-- | arch/ia64/kernel/fsys.S | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/head.S | 4 | ||||
-rw-r--r-- | arch/ia64/kernel/ivt.S | 8 | ||||
-rw-r--r-- | arch/ia64/kernel/minstate.h | 2 | ||||
-rw-r--r-- | arch/ia64/kernel/time.c | 5 |
7 files changed, 21 insertions, 20 deletions
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index a48bd9a9927b..46c9e3007315 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c | |||
@@ -41,7 +41,7 @@ void foo(void) | |||
41 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 41 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
42 | DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); | 42 | DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); |
43 | DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); | 43 | DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); |
44 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 44 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
45 | DEFINE(TI_AC_STAMP, offsetof(struct thread_info, ac_stamp)); | 45 | DEFINE(TI_AC_STAMP, offsetof(struct thread_info, ac_stamp)); |
46 | DEFINE(TI_AC_LEAVE, offsetof(struct thread_info, ac_leave)); | 46 | DEFINE(TI_AC_LEAVE, offsetof(struct thread_info, ac_leave)); |
47 | DEFINE(TI_AC_STIME, offsetof(struct thread_info, ac_stime)); | 47 | DEFINE(TI_AC_STIME, offsetof(struct thread_info, ac_stime)); |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 6bfd8429ee0f..7a53530f22c2 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -724,7 +724,7 @@ GLOBAL_ENTRY(__paravirt_leave_syscall) | |||
724 | #endif | 724 | #endif |
725 | .global __paravirt_work_processed_syscall; | 725 | .global __paravirt_work_processed_syscall; |
726 | __paravirt_work_processed_syscall: | 726 | __paravirt_work_processed_syscall: |
727 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 727 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
728 | adds r2=PT(LOADRS)+16,r12 | 728 | adds r2=PT(LOADRS)+16,r12 |
729 | MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave | 729 | MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave |
730 | adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 | 730 | adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 |
@@ -762,7 +762,7 @@ __paravirt_work_processed_syscall: | |||
762 | 762 | ||
763 | ld8 r29=[r2],16 // M0|1 load cr.ipsr | 763 | ld8 r29=[r2],16 // M0|1 load cr.ipsr |
764 | ld8 r28=[r3],16 // M0|1 load cr.iip | 764 | ld8 r28=[r3],16 // M0|1 load cr.iip |
765 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 765 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
766 | (pUStk) add r14=TI_AC_LEAVE+IA64_TASK_SIZE,r13 | 766 | (pUStk) add r14=TI_AC_LEAVE+IA64_TASK_SIZE,r13 |
767 | ;; | 767 | ;; |
768 | ld8 r30=[r2],16 // M0|1 load cr.ifs | 768 | ld8 r30=[r2],16 // M0|1 load cr.ifs |
@@ -793,7 +793,7 @@ __paravirt_work_processed_syscall: | |||
793 | ld8.fill r1=[r3],16 // M0|1 load r1 | 793 | ld8.fill r1=[r3],16 // M0|1 load r1 |
794 | (pUStk) mov r17=1 // A | 794 | (pUStk) mov r17=1 // A |
795 | ;; | 795 | ;; |
796 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 796 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
797 | (pUStk) st1 [r15]=r17 // M2|3 | 797 | (pUStk) st1 [r15]=r17 // M2|3 |
798 | #else | 798 | #else |
799 | (pUStk) st1 [r14]=r17 // M2|3 | 799 | (pUStk) st1 [r14]=r17 // M2|3 |
@@ -813,7 +813,7 @@ __paravirt_work_processed_syscall: | |||
813 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition | 813 | shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition |
814 | COVER // B add current frame into dirty partition & set cr.ifs | 814 | COVER // B add current frame into dirty partition & set cr.ifs |
815 | ;; | 815 | ;; |
816 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 816 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
817 | mov r19=ar.bsp // M2 get new backing store pointer | 817 | mov r19=ar.bsp // M2 get new backing store pointer |
818 | st8 [r14]=r22 // M save time at leave | 818 | st8 [r14]=r22 // M save time at leave |
819 | mov f10=f0 // F clear f10 | 819 | mov f10=f0 // F clear f10 |
@@ -948,7 +948,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) | |||
948 | adds r16=PT(CR_IPSR)+16,r12 | 948 | adds r16=PT(CR_IPSR)+16,r12 |
949 | adds r17=PT(CR_IIP)+16,r12 | 949 | adds r17=PT(CR_IIP)+16,r12 |
950 | 950 | ||
951 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 951 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
952 | .pred.rel.mutex pUStk,pKStk | 952 | .pred.rel.mutex pUStk,pKStk |
953 | MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled | 953 | MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled |
954 | MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave | 954 | MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave |
@@ -981,7 +981,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) | |||
981 | ;; | 981 | ;; |
982 | ld8.fill r12=[r16],16 | 982 | ld8.fill r12=[r16],16 |
983 | ld8.fill r13=[r17],16 | 983 | ld8.fill r13=[r17],16 |
984 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 984 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
985 | (pUStk) adds r3=TI_AC_LEAVE+IA64_TASK_SIZE,r18 | 985 | (pUStk) adds r3=TI_AC_LEAVE+IA64_TASK_SIZE,r18 |
986 | #else | 986 | #else |
987 | (pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 | 987 | (pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 |
@@ -989,7 +989,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) | |||
989 | ;; | 989 | ;; |
990 | ld8 r20=[r16],16 // ar.fpsr | 990 | ld8 r20=[r16],16 // ar.fpsr |
991 | ld8.fill r15=[r17],16 | 991 | ld8.fill r15=[r17],16 |
992 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 992 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
993 | (pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 // deferred | 993 | (pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 // deferred |
994 | #endif | 994 | #endif |
995 | ;; | 995 | ;; |
@@ -997,7 +997,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel) | |||
997 | ld8.fill r2=[r17] | 997 | ld8.fill r2=[r17] |
998 | (pUStk) mov r17=1 | 998 | (pUStk) mov r17=1 |
999 | ;; | 999 | ;; |
1000 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 1000 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
1001 | // mmi_ : ld8 st1 shr;; mmi_ : st8 st1 shr;; | 1001 | // mmi_ : ld8 st1 shr;; mmi_ : st8 st1 shr;; |
1002 | // mib : mov add br -> mib : ld8 add br | 1002 | // mib : mov add br -> mib : ld8 add br |
1003 | // bbb_ : br nop cover;; mbb_ : mov br cover;; | 1003 | // bbb_ : br nop cover;; mbb_ : mov br cover;; |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index e662f178b990..c4cd45d97749 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -529,7 +529,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) | |||
529 | nop.i 0 | 529 | nop.i 0 |
530 | ;; | 530 | ;; |
531 | mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 | 531 | mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 |
532 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 532 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
533 | MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting | 533 | MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting |
534 | #else | 534 | #else |
535 | nop.m 0 | 535 | nop.m 0 |
@@ -555,7 +555,7 @@ GLOBAL_ENTRY(paravirt_fsys_bubble_down) | |||
555 | cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 | 555 | cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 |
556 | br.call.sptk.many b7=ia64_syscall_setup // B | 556 | br.call.sptk.many b7=ia64_syscall_setup // B |
557 | ;; | 557 | ;; |
558 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 558 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
559 | // mov.m r30=ar.itc is called in advance | 559 | // mov.m r30=ar.itc is called in advance |
560 | add r16=TI_AC_STAMP+IA64_TASK_SIZE,r2 | 560 | add r16=TI_AC_STAMP+IA64_TASK_SIZE,r2 |
561 | add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r2 | 561 | add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r2 |
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 4738ff7bd66a..9be4e497f3d3 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S | |||
@@ -1073,7 +1073,7 @@ END(ia64_native_sched_clock) | |||
1073 | sched_clock = ia64_native_sched_clock | 1073 | sched_clock = ia64_native_sched_clock |
1074 | #endif | 1074 | #endif |
1075 | 1075 | ||
1076 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 1076 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
1077 | GLOBAL_ENTRY(cycle_to_cputime) | 1077 | GLOBAL_ENTRY(cycle_to_cputime) |
1078 | alloc r16=ar.pfs,1,0,0,0 | 1078 | alloc r16=ar.pfs,1,0,0,0 |
1079 | addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 | 1079 | addl r8=THIS_CPU(ia64_cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0 |
@@ -1091,7 +1091,7 @@ GLOBAL_ENTRY(cycle_to_cputime) | |||
1091 | shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT | 1091 | shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT |
1092 | br.ret.sptk.many rp | 1092 | br.ret.sptk.many rp |
1093 | END(cycle_to_cputime) | 1093 | END(cycle_to_cputime) |
1094 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 1094 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
1095 | 1095 | ||
1096 | #ifdef CONFIG_IA64_BRL_EMU | 1096 | #ifdef CONFIG_IA64_BRL_EMU |
1097 | 1097 | ||
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index fa25689fc453..689ffcaa284e 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S | |||
@@ -784,7 +784,7 @@ ENTRY(break_fault) | |||
784 | 784 | ||
785 | (p8) adds r28=16,r28 // A switch cr.iip to next bundle | 785 | (p8) adds r28=16,r28 // A switch cr.iip to next bundle |
786 | (p9) adds r8=1,r8 // A increment ei to next slot | 786 | (p9) adds r8=1,r8 // A increment ei to next slot |
787 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 787 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
788 | ;; | 788 | ;; |
789 | mov b6=r30 // I0 setup syscall handler branch reg early | 789 | mov b6=r30 // I0 setup syscall handler branch reg early |
790 | #else | 790 | #else |
@@ -801,7 +801,7 @@ ENTRY(break_fault) | |||
801 | // | 801 | // |
802 | /////////////////////////////////////////////////////////////////////// | 802 | /////////////////////////////////////////////////////////////////////// |
803 | st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag | 803 | st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag |
804 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 804 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
805 | MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting | 805 | MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting |
806 | #else | 806 | #else |
807 | mov b6=r30 // I0 setup syscall handler branch reg early | 807 | mov b6=r30 // I0 setup syscall handler branch reg early |
@@ -817,7 +817,7 @@ ENTRY(break_fault) | |||
817 | cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? | 817 | cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? |
818 | br.call.sptk.many b7=ia64_syscall_setup // B | 818 | br.call.sptk.many b7=ia64_syscall_setup // B |
819 | 1: | 819 | 1: |
820 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 820 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
821 | // mov.m r30=ar.itc is called in advance, and r13 is current | 821 | // mov.m r30=ar.itc is called in advance, and r13 is current |
822 | add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 // A | 822 | add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13 // A |
823 | add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 // A | 823 | add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13 // A |
@@ -1043,7 +1043,7 @@ END(ia64_syscall_setup) | |||
1043 | DBG_FAULT(16) | 1043 | DBG_FAULT(16) |
1044 | FAULT(16) | 1044 | FAULT(16) |
1045 | 1045 | ||
1046 | #if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE) | 1046 | #if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(__IA64_ASM_PARAVIRTUALIZED_NATIVE) |
1047 | /* | 1047 | /* |
1048 | * There is no particular reason for this code to be here, other than | 1048 | * There is no particular reason for this code to be here, other than |
1049 | * that there happens to be space here that would go unused otherwise. | 1049 | * that there happens to be space here that would go unused otherwise. |
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h index d56753a11636..cc82a7d744c9 100644 --- a/arch/ia64/kernel/minstate.h +++ b/arch/ia64/kernel/minstate.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "entry.h" | 4 | #include "entry.h" |
5 | #include "paravirt_inst.h" | 5 | #include "paravirt_inst.h" |
6 | 6 | ||
7 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 7 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
8 | /* read ar.itc in advance, and use it before leaving bank 0 */ | 8 | /* read ar.itc in advance, and use it before leaving bank 0 */ |
9 | #define ACCOUNT_GET_STAMP \ | 9 | #define ACCOUNT_GET_STAMP \ |
10 | (pUStk) mov.m r20=ar.itc; | 10 | (pUStk) mov.m r20=ar.itc; |
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 88a794536bc0..fbaac1afb844 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -77,7 +77,7 @@ static struct clocksource clocksource_itc = { | |||
77 | }; | 77 | }; |
78 | static struct clocksource *itc_clocksource; | 78 | static struct clocksource *itc_clocksource; |
79 | 79 | ||
80 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 80 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
81 | 81 | ||
82 | #include <linux/kernel_stat.h> | 82 | #include <linux/kernel_stat.h> |
83 | 83 | ||
@@ -136,13 +136,14 @@ void vtime_account_system(struct task_struct *tsk) | |||
136 | 136 | ||
137 | account_system_time(tsk, 0, delta, delta); | 137 | account_system_time(tsk, 0, delta, delta); |
138 | } | 138 | } |
139 | EXPORT_SYMBOL_GPL(vtime_account_system); | ||
139 | 140 | ||
140 | void vtime_account_idle(struct task_struct *tsk) | 141 | void vtime_account_idle(struct task_struct *tsk) |
141 | { | 142 | { |
142 | account_idle_time(vtime_delta(tsk)); | 143 | account_idle_time(vtime_delta(tsk)); |
143 | } | 144 | } |
144 | 145 | ||
145 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 146 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
146 | 147 | ||
147 | static irqreturn_t | 148 | static irqreturn_t |
148 | timer_interrupt (int irq, void *dev_id) | 149 | timer_interrupt (int irq, void *dev_id) |