xref: /OK3568_Linux_fs/kernel/arch/powerpc/include/asm/cputime.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Definitions for measuring cputime on powerpc machines.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2006 Paul Mackerras, IBM Corp.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * If we have CONFIG_VIRT_CPU_ACCOUNTING_NATIVE, we measure cpu time in
8*4882a593Smuzhiyun  * the same units as the timebase.  Otherwise we measure cpu time
9*4882a593Smuzhiyun  * in jiffies using the generic definitions.
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #ifndef __POWERPC_CPUTIME_H
13*4882a593Smuzhiyun #define __POWERPC_CPUTIME_H
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <linux/types.h>
18*4882a593Smuzhiyun #include <linux/time.h>
19*4882a593Smuzhiyun #include <asm/div64.h>
20*4882a593Smuzhiyun #include <asm/time.h>
21*4882a593Smuzhiyun #include <asm/param.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun typedef u64 __nocast cputime_t;
24*4882a593Smuzhiyun typedef u64 __nocast cputime64_t;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define cmpxchg_cputime(ptr, old, new) cmpxchg(ptr, old, new)
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #ifdef __KERNEL__
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun  * Convert cputime <-> microseconds
31*4882a593Smuzhiyun  */
32*4882a593Smuzhiyun extern u64 __cputime_usec_factor;
33*4882a593Smuzhiyun 
cputime_to_usecs(const cputime_t ct)34*4882a593Smuzhiyun static inline unsigned long cputime_to_usecs(const cputime_t ct)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	return mulhdu((__force u64) ct, __cputime_usec_factor);
37*4882a593Smuzhiyun }
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define cputime_to_nsecs(cputime) tb_to_ns((__force u64)cputime)
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun  * PPC64 uses PACA which is task independent for storing accounting data while
43*4882a593Smuzhiyun  * PPC32 uses struct thread_info, therefore at task switch the accounting data
44*4882a593Smuzhiyun  * has to be populated in the new task
45*4882a593Smuzhiyun  */
46*4882a593Smuzhiyun #ifdef CONFIG_PPC64
47*4882a593Smuzhiyun #define get_accounting(tsk)	(&get_paca()->accounting)
48*4882a593Smuzhiyun #define raw_get_accounting(tsk)	(&local_paca->accounting)
arch_vtime_task_switch(struct task_struct * tsk)49*4882a593Smuzhiyun static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #else
52*4882a593Smuzhiyun #define get_accounting(tsk)	(&task_thread_info(tsk)->accounting)
53*4882a593Smuzhiyun #define raw_get_accounting(tsk)	get_accounting(tsk)
54*4882a593Smuzhiyun /*
55*4882a593Smuzhiyun  * Called from the context switch with interrupts disabled, to charge all
56*4882a593Smuzhiyun  * accumulated times to the current process, and to prepare accounting on
57*4882a593Smuzhiyun  * the next process.
58*4882a593Smuzhiyun  */
arch_vtime_task_switch(struct task_struct * prev)59*4882a593Smuzhiyun static inline void arch_vtime_task_switch(struct task_struct *prev)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	struct cpu_accounting_data *acct = get_accounting(current);
62*4882a593Smuzhiyun 	struct cpu_accounting_data *acct0 = get_accounting(prev);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	acct->starttime = acct0->starttime;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun #endif
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun /*
69*4882a593Smuzhiyun  * account_cpu_user_entry/exit runs "unreconciled", so can't trace,
70*4882a593Smuzhiyun  * can't use get_paca()
71*4882a593Smuzhiyun  */
account_cpu_user_entry(void)72*4882a593Smuzhiyun static notrace inline void account_cpu_user_entry(void)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	unsigned long tb = mftb();
75*4882a593Smuzhiyun 	struct cpu_accounting_data *acct = raw_get_accounting(current);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	acct->utime += (tb - acct->starttime_user);
78*4882a593Smuzhiyun 	acct->starttime = tb;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
account_cpu_user_exit(void)81*4882a593Smuzhiyun static notrace inline void account_cpu_user_exit(void)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	unsigned long tb = mftb();
84*4882a593Smuzhiyun 	struct cpu_accounting_data *acct = raw_get_accounting(current);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	acct->stime += (tb - acct->starttime);
87*4882a593Smuzhiyun 	acct->starttime_user = tb;
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun #endif /* __KERNEL__ */
92*4882a593Smuzhiyun #else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
account_cpu_user_entry(void)93*4882a593Smuzhiyun static inline void account_cpu_user_entry(void)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun }
account_cpu_user_exit(void)96*4882a593Smuzhiyun static inline void account_cpu_user_exit(void)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
100*4882a593Smuzhiyun #endif /* __POWERPC_CPUTIME_H */
101