diff options
27 files changed, 160 insertions, 54 deletions
diff --git a/arch/ia64/include/asm/cputime.h b/arch/ia64/include/asm/cputime.h index 040b31638001..e2d3f5baf265 100644 --- a/arch/ia64/include/asm/cputime.h +++ b/arch/ia64/include/asm/cputime.h | |||
@@ -11,19 +11,19 @@ | |||
11 | * as published by the Free Software Foundation; either version | 11 | * as published by the Free Software Foundation; either version |
12 | * 2 of the License, or (at your option) any later version. | 12 | * 2 of the License, or (at your option) any later version. |
13 | * | 13 | * |
14 | * If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in nsec. | 14 | * If we have CONFIG_VIRT_CPU_ACCOUNTING_NATIVE, we measure cpu time in nsec. |
15 | * Otherwise we measure cpu time in jiffies using the generic definitions. | 15 | * Otherwise we measure cpu time in jiffies using the generic definitions. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #ifndef __IA64_CPUTIME_H | 18 | #ifndef __IA64_CPUTIME_H |
19 | #define __IA64_CPUTIME_H | 19 | #define __IA64_CPUTIME_H |
20 | 20 | ||
21 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 21 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
22 | # include <asm-generic/cputime.h> | 22 | # include <asm-generic/cputime.h> |
23 | #else | 23 | #else |
24 | # include <asm/processor.h> | 24 | # include <asm/processor.h> |
25 | # include <asm-generic/cputime_nsecs.h> | 25 | # include <asm-generic/cputime_nsecs.h> |
26 | extern void arch_vtime_task_switch(struct task_struct *tsk); | 26 | extern void arch_vtime_task_switch(struct task_struct *tsk); |
27 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 27 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
28 | 28 | ||
29 | #endif /* __IA64_CPUTIME_H */ | 29 | #endif /* __IA64_CPUTIME_H */ |
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index ff2ae4136584..020d655ed082 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h | |||
@@ -31,7 +31,7 @@ struct thread_info { | |||
31 | mm_segment_t addr_limit; /* user-level address space limit */ | 31 | mm_segment_t addr_limit; /* user-level address space limit */ |
32 | int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ | 32 | int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ |
33 | struct restart_block restart_block; | 33 | struct restart_block restart_block; |
34 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 34 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
35 | __u64 ac_stamp; | 35 | __u64 ac_stamp; |
36 | __u64 ac_leave; | 36 | __u64 ac_leave; |
37 | __u64 ac_stime; | 37 | __u64 ac_stime; |
@@ -69,7 +69,7 @@ struct thread_info { | |||
69 | #define task_stack_page(tsk) ((void *)(tsk)) | 69 | #define task_stack_page(tsk) ((void *)(tsk)) |
70 | 70 | ||
71 | #define __HAVE_THREAD_FUNCTIONS | 71 | #define __HAVE_THREAD_FUNCTIONS |
72 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 72 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
73 | #define setup_thread_stack(p, org) \ | 73 | #define setup_thread_stack(p, org) \ |
74 | *task_thread_info(p) = *task_thread_info(org); \ | 74 | *task_thread_info(p) = *task_thread_info(org); \ |
75 | task_thread_info(p)->ac_stime = 0; \ | 75 | task_thread_info(p)->ac_stime = 0; \ |
diff --git a/arch/ia64/include/asm/xen/minstate.h b/arch/ia64/include/asm/xen/minstate.h index c57fa910f2c9..00cf03e0cb82 100644 --- a/arch/ia64/include/asm/xen/minstate.h +++ b/arch/ia64/include/asm/xen/minstate.h | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 2 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
3 | /* read ar.itc in advance, and use it before leaving bank 0 */ | 3 | /* read ar.itc in advance, and use it before leaving bank 0 */ |
4 | #define XEN_ACCOUNT_GET_STAMP \ | 4 | #define XEN_ACCOUNT_GET_STAMP \ |
5 | MOV_FROM_ITC(pUStk, p6, r20, r2); | 5 | MOV_FROM_ITC(pUStk, p6, r20, r2); |
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..a3a3f5a1cb3a 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 | ||
@@ -142,7 +142,7 @@ void vtime_account_idle(struct task_struct *tsk) | |||
142 | account_idle_time(vtime_delta(tsk)); | 142 | account_idle_time(vtime_delta(tsk)); |
143 | } | 143 | } |
144 | 144 | ||
145 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 145 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
146 | 146 | ||
147 | static irqreturn_t | 147 | static irqreturn_t |
148 | timer_interrupt (int irq, void *dev_id) | 148 | timer_interrupt (int irq, void *dev_id) |
diff --git a/arch/powerpc/configs/chroma_defconfig b/arch/powerpc/configs/chroma_defconfig index 29bb11ec6c64..4f35fc462385 100644 --- a/arch/powerpc/configs/chroma_defconfig +++ b/arch/powerpc/configs/chroma_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_PPC_BOOK3E_64=y | 2 | CONFIG_PPC_BOOK3E_64=y |
3 | # CONFIG_VIRT_CPU_ACCOUNTING is not set | 3 | # CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set |
4 | CONFIG_SMP=y | 4 | CONFIG_SMP=y |
5 | CONFIG_NR_CPUS=256 | 5 | CONFIG_NR_CPUS=256 |
6 | CONFIG_EXPERIMENTAL=y | 6 | CONFIG_EXPERIMENTAL=y |
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig b/arch/powerpc/configs/corenet64_smp_defconfig index 88fa5c46f66f..f7df8362911f 100644 --- a/arch/powerpc/configs/corenet64_smp_defconfig +++ b/arch/powerpc/configs/corenet64_smp_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_PPC_BOOK3E_64=y | 2 | CONFIG_PPC_BOOK3E_64=y |
3 | # CONFIG_VIRT_CPU_ACCOUNTING is not set | 3 | # CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set |
4 | CONFIG_SMP=y | 4 | CONFIG_SMP=y |
5 | CONFIG_NR_CPUS=2 | 5 | CONFIG_NR_CPUS=2 |
6 | CONFIG_EXPERIMENTAL=y | 6 | CONFIG_EXPERIMENTAL=y |
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 840a2c2d0430..bcedeea0df89 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | CONFIG_PPC64=y | 1 | CONFIG_PPC64=y |
2 | CONFIG_ALTIVEC=y | 2 | CONFIG_ALTIVEC=y |
3 | # CONFIG_VIRT_CPU_ACCOUNTING is not set | 3 | # CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not set |
4 | CONFIG_SMP=y | 4 | CONFIG_SMP=y |
5 | CONFIG_NR_CPUS=2 | 5 | CONFIG_NR_CPUS=2 |
6 | CONFIG_EXPERIMENTAL=y | 6 | CONFIG_EXPERIMENTAL=y |
diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 483733bd06d4..607559ab271f 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h | |||
@@ -8,7 +8,7 @@ | |||
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in | 11 | * If we have CONFIG_VIRT_CPU_ACCOUNTING_NATIVE, we measure cpu time in |
12 | * the same units as the timebase. Otherwise we measure cpu time | 12 | * the same units as the timebase. Otherwise we measure cpu time |
13 | * in jiffies using the generic definitions. | 13 | * in jiffies using the generic definitions. |
14 | */ | 14 | */ |
@@ -16,7 +16,7 @@ | |||
16 | #ifndef __POWERPC_CPUTIME_H | 16 | #ifndef __POWERPC_CPUTIME_H |
17 | #define __POWERPC_CPUTIME_H | 17 | #define __POWERPC_CPUTIME_H |
18 | 18 | ||
19 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 19 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
20 | #include <asm-generic/cputime.h> | 20 | #include <asm-generic/cputime.h> |
21 | #ifdef __KERNEL__ | 21 | #ifdef __KERNEL__ |
22 | static inline void setup_cputime_one_jiffy(void) { } | 22 | static inline void setup_cputime_one_jiffy(void) { } |
@@ -231,5 +231,5 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk) | |||
231 | static inline void arch_vtime_task_switch(struct task_struct *tsk) { } | 231 | static inline void arch_vtime_task_switch(struct task_struct *tsk) { } |
232 | 232 | ||
233 | #endif /* __KERNEL__ */ | 233 | #endif /* __KERNEL__ */ |
234 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 234 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
235 | #endif /* __POWERPC_CPUTIME_H */ | 235 | #endif /* __POWERPC_CPUTIME_H */ |
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 531fe0c3108f..b1e7f2af1016 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h | |||
@@ -145,7 +145,7 @@ struct dtl_entry { | |||
145 | extern struct kmem_cache *dtl_cache; | 145 | extern struct kmem_cache *dtl_cache; |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * When CONFIG_VIRT_CPU_ACCOUNTING = y, the cpu accounting code controls | 148 | * When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE = y, the cpu accounting code controls |
149 | * reading from the dispatch trace log. If other code wants to consume | 149 | * reading from the dispatch trace log. If other code wants to consume |
150 | * DTL entries, it can set this pointer to a function that will get | 150 | * DTL entries, it can set this pointer to a function that will get |
151 | * called once for each DTL entry that gets processed. | 151 | * called once for each DTL entry that gets processed. |
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index ea2a86e8ff95..2d0e1f5d8339 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -24,7 +24,7 @@ | |||
24 | * user_time and system_time fields in the paca. | 24 | * user_time and system_time fields in the paca. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 27 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
28 | #define ACCOUNT_CPU_USER_ENTRY(ra, rb) | 28 | #define ACCOUNT_CPU_USER_ENTRY(ra, rb) |
29 | #define ACCOUNT_CPU_USER_EXIT(ra, rb) | 29 | #define ACCOUNT_CPU_USER_EXIT(ra, rb) |
30 | #define ACCOUNT_STOLEN_TIME | 30 | #define ACCOUNT_STOLEN_TIME |
@@ -70,7 +70,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | |||
70 | 70 | ||
71 | #endif /* CONFIG_PPC_SPLPAR */ | 71 | #endif /* CONFIG_PPC_SPLPAR */ |
72 | 72 | ||
73 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 73 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Macros for storing registers into and loading registers from | 76 | * Macros for storing registers into and loading registers from |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index b310a0573625..a0ca42fb1541 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -94,7 +94,7 @@ system_call_common: | |||
94 | addi r9,r1,STACK_FRAME_OVERHEAD | 94 | addi r9,r1,STACK_FRAME_OVERHEAD |
95 | ld r11,exception_marker@toc(r2) | 95 | ld r11,exception_marker@toc(r2) |
96 | std r11,-16(r9) /* "regshere" marker */ | 96 | std r11,-16(r9) /* "regshere" marker */ |
97 | #if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR) | 97 | #if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE) && defined(CONFIG_PPC_SPLPAR) |
98 | BEGIN_FW_FTR_SECTION | 98 | BEGIN_FW_FTR_SECTION |
99 | beq 33f | 99 | beq 33f |
100 | /* if from user, see if there are any DTL entries to process */ | 100 | /* if from user, see if there are any DTL entries to process */ |
@@ -110,7 +110,7 @@ BEGIN_FW_FTR_SECTION | |||
110 | addi r9,r1,STACK_FRAME_OVERHEAD | 110 | addi r9,r1,STACK_FRAME_OVERHEAD |
111 | 33: | 111 | 33: |
112 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) | 112 | END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) |
113 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING && CONFIG_PPC_SPLPAR */ | 113 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE && CONFIG_PPC_SPLPAR */ |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * A syscall should always be called with interrupts enabled | 116 | * A syscall should always be called with interrupts enabled |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 6f6b1cccc916..22c9b67f9983 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -143,7 +143,7 @@ EXPORT_SYMBOL_GPL(ppc_proc_freq); | |||
143 | unsigned long ppc_tb_freq; | 143 | unsigned long ppc_tb_freq; |
144 | EXPORT_SYMBOL_GPL(ppc_tb_freq); | 144 | EXPORT_SYMBOL_GPL(ppc_tb_freq); |
145 | 145 | ||
146 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 146 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
147 | /* | 147 | /* |
148 | * Factors for converting from cputime_t (timebase ticks) to | 148 | * Factors for converting from cputime_t (timebase ticks) to |
149 | * jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds). | 149 | * jiffies, microseconds, seconds, and clock_t (1/USER_HZ seconds). |
@@ -377,7 +377,7 @@ void vtime_account_user(struct task_struct *tsk) | |||
377 | account_user_time(tsk, utime, utimescaled); | 377 | account_user_time(tsk, utime, utimescaled); |
378 | } | 378 | } |
379 | 379 | ||
380 | #else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ | 380 | #else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
381 | #define calc_cputime_factors() | 381 | #define calc_cputime_factors() |
382 | #endif | 382 | #endif |
383 | 383 | ||
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index a7648543c59e..0cc0ac07a55d 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c | |||
@@ -57,7 +57,7 @@ static u8 dtl_event_mask = 0x7; | |||
57 | */ | 57 | */ |
58 | static int dtl_buf_entries = N_DISPATCH_LOG; | 58 | static int dtl_buf_entries = N_DISPATCH_LOG; |
59 | 59 | ||
60 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 60 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
61 | struct dtl_ring { | 61 | struct dtl_ring { |
62 | u64 write_index; | 62 | u64 write_index; |
63 | struct dtl_entry *write_ptr; | 63 | struct dtl_entry *write_ptr; |
@@ -142,7 +142,7 @@ static u64 dtl_current_index(struct dtl *dtl) | |||
142 | return per_cpu(dtl_rings, dtl->cpu).write_index; | 142 | return per_cpu(dtl_rings, dtl->cpu).write_index; |
143 | } | 143 | } |
144 | 144 | ||
145 | #else /* CONFIG_VIRT_CPU_ACCOUNTING */ | 145 | #else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
146 | 146 | ||
147 | static int dtl_start(struct dtl *dtl) | 147 | static int dtl_start(struct dtl *dtl) |
148 | { | 148 | { |
@@ -188,7 +188,7 @@ static u64 dtl_current_index(struct dtl *dtl) | |||
188 | { | 188 | { |
189 | return lppaca_of(dtl->cpu).dtl_idx; | 189 | return lppaca_of(dtl->cpu).dtl_idx; |
190 | } | 190 | } |
191 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 191 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
192 | 192 | ||
193 | static int dtl_enable(struct dtl *dtl) | 193 | static int dtl_enable(struct dtl *dtl) |
194 | { | 194 | { |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index ca55882465d6..527e12c9573b 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -281,7 +281,7 @@ static struct notifier_block pci_dn_reconfig_nb = { | |||
281 | 281 | ||
282 | struct kmem_cache *dtl_cache; | 282 | struct kmem_cache *dtl_cache; |
283 | 283 | ||
284 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 284 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
285 | /* | 285 | /* |
286 | * Allocate space for the dispatch trace log for all possible cpus | 286 | * Allocate space for the dispatch trace log for all possible cpus |
287 | * and register the buffers with the hypervisor. This is used for | 287 | * and register the buffers with the hypervisor. This is used for |
@@ -332,12 +332,12 @@ static int alloc_dispatch_logs(void) | |||
332 | 332 | ||
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | #else /* !CONFIG_VIRT_CPU_ACCOUNTING */ | 335 | #else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
336 | static inline int alloc_dispatch_logs(void) | 336 | static inline int alloc_dispatch_logs(void) |
337 | { | 337 | { |
338 | return 0; | 338 | return 0; |
339 | } | 339 | } |
340 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ | 340 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */ |
341 | 341 | ||
342 | static int alloc_dispatch_log_kmem_cache(void) | 342 | static int alloc_dispatch_log_kmem_cache(void) |
343 | { | 343 | { |
diff --git a/include/asm-generic/cputime.h b/include/asm-generic/cputime.h index c6eddf50eaf9..51969436b8b8 100644 --- a/include/asm-generic/cputime.h +++ b/include/asm-generic/cputime.h | |||
@@ -4,6 +4,12 @@ | |||
4 | #include <linux/time.h> | 4 | #include <linux/time.h> |
5 | #include <linux/jiffies.h> | 5 | #include <linux/jiffies.h> |
6 | 6 | ||
7 | #include <asm-generic/cputime_jiffies.h> | 7 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
8 | # include <asm-generic/cputime_jiffies.h> | ||
9 | #endif | ||
10 | |||
11 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | ||
12 | # include <asm-generic/cputime_nsecs.h> | ||
13 | #endif | ||
8 | 14 | ||
9 | #endif | 15 | #endif |
diff --git a/include/asm-generic/cputime_nsecs.h b/include/asm-generic/cputime_nsecs.h index c73d182f4751..b6485cafb7bd 100644 --- a/include/asm-generic/cputime_nsecs.h +++ b/include/asm-generic/cputime_nsecs.h | |||
@@ -26,6 +26,7 @@ typedef u64 __nocast cputime64_t; | |||
26 | */ | 26 | */ |
27 | #define cputime_to_jiffies(__ct) \ | 27 | #define cputime_to_jiffies(__ct) \ |
28 | ((__force u64)(__ct) / (NSEC_PER_SEC / HZ)) | 28 | ((__force u64)(__ct) / (NSEC_PER_SEC / HZ)) |
29 | #define cputime_to_scaled(__ct) (__ct) | ||
29 | #define jiffies_to_cputime(__jif) \ | 30 | #define jiffies_to_cputime(__jif) \ |
30 | (__force cputime_t)((__jif) * (NSEC_PER_SEC / HZ)) | 31 | (__force cputime_t)((__jif) * (NSEC_PER_SEC / HZ)) |
31 | #define cputime64_to_jiffies64(__ct) \ | 32 | #define cputime64_to_jiffies64(__ct) \ |
@@ -33,6 +34,13 @@ typedef u64 __nocast cputime64_t; | |||
33 | #define jiffies64_to_cputime64(__jif) \ | 34 | #define jiffies64_to_cputime64(__jif) \ |
34 | (__force cputime64_t)((__jif) * (NSEC_PER_SEC / HZ)) | 35 | (__force cputime64_t)((__jif) * (NSEC_PER_SEC / HZ)) |
35 | 36 | ||
37 | |||
38 | /* | ||
39 | * Convert cputime <-> nanoseconds | ||
40 | */ | ||
41 | #define nsecs_to_cputime(__nsecs) ((__force u64)(__nsecs)) | ||
42 | |||
43 | |||
36 | /* | 44 | /* |
37 | * Convert cputime <-> microseconds | 45 | * Convert cputime <-> microseconds |
38 | */ | 46 | */ |
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 66b70780e910..ed5f6ed6eb77 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h | |||
@@ -127,7 +127,7 @@ extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t) | |||
127 | extern void account_steal_time(cputime_t); | 127 | extern void account_steal_time(cputime_t); |
128 | extern void account_idle_time(cputime_t); | 128 | extern void account_idle_time(cputime_t); |
129 | 129 | ||
130 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 130 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE |
131 | static inline void account_process_tick(struct task_struct *tsk, int user) | 131 | static inline void account_process_tick(struct task_struct *tsk, int user) |
132 | { | 132 | { |
133 | vtime_account_user(tsk); | 133 | vtime_account_user(tsk); |
diff --git a/include/linux/vtime.h b/include/linux/vtime.h index ae30ab58431a..21ef703d1b25 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h | |||
@@ -14,9 +14,25 @@ extern void vtime_account(struct task_struct *tsk); | |||
14 | static inline void vtime_task_switch(struct task_struct *prev) { } | 14 | static inline void vtime_task_switch(struct task_struct *prev) { } |
15 | static inline void vtime_account_system(struct task_struct *tsk) { } | 15 | static inline void vtime_account_system(struct task_struct *tsk) { } |
16 | static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { } | 16 | static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { } |
17 | static inline void vtime_account_user(struct task_struct *tsk) { } | ||
17 | static inline void vtime_account(struct task_struct *tsk) { } | 18 | static inline void vtime_account(struct task_struct *tsk) { } |
18 | #endif | 19 | #endif |
19 | 20 | ||
21 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | ||
22 | static inline void arch_vtime_task_switch(struct task_struct *tsk) { } | ||
23 | static inline void vtime_user_enter(struct task_struct *tsk) | ||
24 | { | ||
25 | vtime_account_system(tsk); | ||
26 | } | ||
27 | static inline void vtime_user_exit(struct task_struct *tsk) | ||
28 | { | ||
29 | vtime_account_user(tsk); | ||
30 | } | ||
31 | #else | ||
32 | static inline void vtime_user_enter(struct task_struct *tsk) { } | ||
33 | static inline void vtime_user_exit(struct task_struct *tsk) { } | ||
34 | #endif | ||
35 | |||
20 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | 36 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING |
21 | extern void irqtime_account_irq(struct task_struct *tsk); | 37 | extern void irqtime_account_irq(struct task_struct *tsk); |
22 | #else | 38 | #else |
diff --git a/init/Kconfig b/init/Kconfig index be8b7f55312d..a05f843e7e52 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -326,6 +326,9 @@ source "kernel/time/Kconfig" | |||
326 | 326 | ||
327 | menu "CPU/Task time and stats accounting" | 327 | menu "CPU/Task time and stats accounting" |
328 | 328 | ||
329 | config VIRT_CPU_ACCOUNTING | ||
330 | bool | ||
331 | |||
329 | choice | 332 | choice |
330 | prompt "Cputime accounting" | 333 | prompt "Cputime accounting" |
331 | default TICK_CPU_ACCOUNTING if !PPC64 | 334 | default TICK_CPU_ACCOUNTING if !PPC64 |
@@ -342,9 +345,10 @@ config TICK_CPU_ACCOUNTING | |||
342 | 345 | ||
343 | If unsure, say Y. | 346 | If unsure, say Y. |
344 | 347 | ||
345 | config VIRT_CPU_ACCOUNTING | 348 | config VIRT_CPU_ACCOUNTING_NATIVE |
346 | bool "Deterministic task and CPU time accounting" | 349 | bool "Deterministic task and CPU time accounting" |
347 | depends on HAVE_VIRT_CPU_ACCOUNTING | 350 | depends on HAVE_VIRT_CPU_ACCOUNTING |
351 | select VIRT_CPU_ACCOUNTING | ||
348 | help | 352 | help |
349 | Select this option to enable more accurate task and CPU time | 353 | Select this option to enable more accurate task and CPU time |
350 | accounting. This is done by reading a CPU counter on each | 354 | accounting. This is done by reading a CPU counter on each |
@@ -354,6 +358,23 @@ config VIRT_CPU_ACCOUNTING | |||
354 | this also enables accounting of stolen time on logically-partitioned | 358 | this also enables accounting of stolen time on logically-partitioned |
355 | systems. | 359 | systems. |
356 | 360 | ||
361 | config VIRT_CPU_ACCOUNTING_GEN | ||
362 | bool "Full dynticks CPU time accounting" | ||
363 | depends on HAVE_CONTEXT_TRACKING && 64BIT | ||
364 | select VIRT_CPU_ACCOUNTING | ||
365 | select CONTEXT_TRACKING | ||
366 | help | ||
367 | Select this option to enable task and CPU time accounting on full | ||
368 | dynticks systems. This accounting is implemented by watching every | ||
369 | kernel-user boundaries using the context tracking subsystem. | ||
370 | The accounting is thus performed at the expense of some significant | ||
371 | overhead. | ||
372 | |||
373 | For now this is only useful if you are working on the full | ||
374 | dynticks subsystem development. | ||
375 | |||
376 | If unsure, say N. | ||
377 | |||
357 | config IRQ_TIME_ACCOUNTING | 378 | config IRQ_TIME_ACCOUNTING |
358 | bool "Fine granularity task level IRQ time accounting" | 379 | bool "Fine granularity task level IRQ time accounting" |
359 | depends on HAVE_IRQ_TIME_ACCOUNTING | 380 | depends on HAVE_IRQ_TIME_ACCOUNTING |
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 54f471e536dc..9002e92e6372 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c | |||
@@ -30,8 +30,9 @@ void user_enter(void) | |||
30 | local_irq_save(flags); | 30 | local_irq_save(flags); |
31 | if (__this_cpu_read(context_tracking.active) && | 31 | if (__this_cpu_read(context_tracking.active) && |
32 | __this_cpu_read(context_tracking.state) != IN_USER) { | 32 | __this_cpu_read(context_tracking.state) != IN_USER) { |
33 | __this_cpu_write(context_tracking.state, IN_USER); | 33 | vtime_user_enter(current); |
34 | rcu_user_enter(); | 34 | rcu_user_enter(); |
35 | __this_cpu_write(context_tracking.state, IN_USER); | ||
35 | } | 36 | } |
36 | local_irq_restore(flags); | 37 | local_irq_restore(flags); |
37 | } | 38 | } |
@@ -53,8 +54,9 @@ void user_exit(void) | |||
53 | 54 | ||
54 | local_irq_save(flags); | 55 | local_irq_save(flags); |
55 | if (__this_cpu_read(context_tracking.state) == IN_USER) { | 56 | if (__this_cpu_read(context_tracking.state) == IN_USER) { |
56 | __this_cpu_write(context_tracking.state, IN_KERNEL); | ||
57 | rcu_user_exit(); | 57 | rcu_user_exit(); |
58 | vtime_user_exit(current); | ||
59 | __this_cpu_write(context_tracking.state, IN_KERNEL); | ||
58 | } | 60 | } |
59 | local_irq_restore(flags); | 61 | local_irq_restore(flags); |
60 | } | 62 | } |
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 5849448b981e..1c964eced92c 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/tsacct_kern.h> | 3 | #include <linux/tsacct_kern.h> |
4 | #include <linux/kernel_stat.h> | 4 | #include <linux/kernel_stat.h> |
5 | #include <linux/static_key.h> | 5 | #include <linux/static_key.h> |
6 | #include <linux/context_tracking.h> | ||
6 | #include "sched.h" | 7 | #include "sched.h" |
7 | 8 | ||
8 | 9 | ||
@@ -479,7 +480,9 @@ void vtime_task_switch(struct task_struct *prev) | |||
479 | else | 480 | else |
480 | vtime_account_system(prev); | 481 | vtime_account_system(prev); |
481 | 482 | ||
483 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE | ||
482 | vtime_account_user(prev); | 484 | vtime_account_user(prev); |
485 | #endif | ||
483 | arch_vtime_task_switch(prev); | 486 | arch_vtime_task_switch(prev); |
484 | } | 487 | } |
485 | #endif | 488 | #endif |
@@ -495,10 +498,24 @@ void vtime_task_switch(struct task_struct *prev) | |||
495 | #ifndef __ARCH_HAS_VTIME_ACCOUNT | 498 | #ifndef __ARCH_HAS_VTIME_ACCOUNT |
496 | void vtime_account(struct task_struct *tsk) | 499 | void vtime_account(struct task_struct *tsk) |
497 | { | 500 | { |
498 | if (in_interrupt() || !is_idle_task(tsk)) | 501 | if (!in_interrupt()) { |
499 | vtime_account_system(tsk); | 502 | /* |
500 | else | 503 | * If we interrupted user, context_tracking_in_user() |
501 | vtime_account_idle(tsk); | 504 | * is 1 because the context tracking don't hook |
505 | * on irq entry/exit. This way we know if | ||
506 | * we need to flush user time on kernel entry. | ||
507 | */ | ||
508 | if (context_tracking_in_user()) { | ||
509 | vtime_account_user(tsk); | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | if (is_idle_task(tsk)) { | ||
514 | vtime_account_idle(tsk); | ||
515 | return; | ||
516 | } | ||
517 | } | ||
518 | vtime_account_system(tsk); | ||
502 | } | 519 | } |
503 | EXPORT_SYMBOL_GPL(vtime_account); | 520 | EXPORT_SYMBOL_GPL(vtime_account); |
504 | #endif /* __ARCH_HAS_VTIME_ACCOUNT */ | 521 | #endif /* __ARCH_HAS_VTIME_ACCOUNT */ |
@@ -583,3 +600,39 @@ void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime | |||
583 | cputime_adjust(&cputime, &p->signal->prev_cputime, ut, st); | 600 | cputime_adjust(&cputime, &p->signal->prev_cputime, ut, st); |
584 | } | 601 | } |
585 | #endif | 602 | #endif |
603 | |||
604 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN | ||
605 | static DEFINE_PER_CPU(unsigned long long, cputime_snap); | ||
606 | |||
607 | static cputime_t get_vtime_delta(void) | ||
608 | { | ||
609 | unsigned long long delta; | ||
610 | |||
611 | delta = sched_clock() - __this_cpu_read(cputime_snap); | ||
612 | __this_cpu_add(cputime_snap, delta); | ||
613 | |||
614 | /* CHECKME: always safe to convert nsecs to cputime? */ | ||
615 | return nsecs_to_cputime(delta); | ||
616 | } | ||
617 | |||
618 | void vtime_account_system(struct task_struct *tsk) | ||
619 | { | ||
620 | cputime_t delta_cpu = get_vtime_delta(); | ||
621 | |||
622 | account_system_time(tsk, irq_count(), delta_cpu, cputime_to_scaled(delta_cpu)); | ||
623 | } | ||
624 | |||
625 | void vtime_account_user(struct task_struct *tsk) | ||
626 | { | ||
627 | cputime_t delta_cpu = get_vtime_delta(); | ||
628 | |||
629 | account_user_time(tsk, delta_cpu, cputime_to_scaled(delta_cpu)); | ||
630 | } | ||
631 | |||
632 | void vtime_account_idle(struct task_struct *tsk) | ||
633 | { | ||
634 | cputime_t delta_cpu = get_vtime_delta(); | ||
635 | |||
636 | account_idle_time(delta_cpu); | ||
637 | } | ||
638 | #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ | ||