Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Definitions for measuring cputime on powerpc machines.
0004  *
0005  * Copyright (C) 2006 Paul Mackerras, IBM Corp.
0006  *
0007  * If we have CONFIG_VIRT_CPU_ACCOUNTING_NATIVE, we measure cpu time in
0008  * the same units as the timebase.  Otherwise we measure cpu time
0009  * in jiffies using the generic definitions.
0010  */
0011 
0012 #ifndef __POWERPC_CPUTIME_H
0013 #define __POWERPC_CPUTIME_H
0014 
0015 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
0016 
0017 #include <linux/types.h>
0018 #include <linux/time.h>
0019 #include <asm/div64.h>
0020 #include <asm/time.h>
0021 #include <asm/param.h>
0022 #include <asm/firmware.h>
0023 
0024 typedef u64 __nocast cputime_t;
0025 typedef u64 __nocast cputime64_t;
0026 
0027 #define cmpxchg_cputime(ptr, old, new) cmpxchg(ptr, old, new)
0028 
0029 #ifdef __KERNEL__
0030 /*
0031  * Convert cputime <-> microseconds
0032  */
0033 extern u64 __cputime_usec_factor;
0034 
0035 static inline unsigned long cputime_to_usecs(const cputime_t ct)
0036 {
0037     return mulhdu((__force u64) ct, __cputime_usec_factor);
0038 }
0039 
0040 #define cputime_to_nsecs(cputime) tb_to_ns((__force u64)cputime)
0041 
0042 /*
0043  * PPC64 uses PACA which is task independent for storing accounting data while
0044  * PPC32 uses struct thread_info, therefore at task switch the accounting data
0045  * has to be populated in the new task
0046  */
0047 #ifdef CONFIG_PPC64
0048 #define get_accounting(tsk) (&get_paca()->accounting)
0049 #define raw_get_accounting(tsk) (&local_paca->accounting)
0050 static inline void arch_vtime_task_switch(struct task_struct *tsk) { }
0051 
0052 #else
0053 #define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
0054 #define raw_get_accounting(tsk) get_accounting(tsk)
0055 /*
0056  * Called from the context switch with interrupts disabled, to charge all
0057  * accumulated times to the current process, and to prepare accounting on
0058  * the next process.
0059  */
0060 static inline void arch_vtime_task_switch(struct task_struct *prev)
0061 {
0062     struct cpu_accounting_data *acct = get_accounting(current);
0063     struct cpu_accounting_data *acct0 = get_accounting(prev);
0064 
0065     acct->starttime = acct0->starttime;
0066 }
0067 #endif
0068 
0069 /*
0070  * account_cpu_user_entry/exit runs "unreconciled", so can't trace,
0071  * can't use get_paca()
0072  */
0073 static notrace inline void account_cpu_user_entry(void)
0074 {
0075     unsigned long tb = mftb();
0076     struct cpu_accounting_data *acct = raw_get_accounting(current);
0077 
0078     acct->utime += (tb - acct->starttime_user);
0079     acct->starttime = tb;
0080 }
0081 
0082 static notrace inline void account_cpu_user_exit(void)
0083 {
0084     unsigned long tb = mftb();
0085     struct cpu_accounting_data *acct = raw_get_accounting(current);
0086 
0087     acct->stime += (tb - acct->starttime);
0088     acct->starttime_user = tb;
0089 }
0090 
0091 static notrace inline void account_stolen_time(void)
0092 {
0093 #ifdef CONFIG_PPC_SPLPAR
0094     if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
0095         struct lppaca *lp = local_paca->lppaca_ptr;
0096 
0097         if (unlikely(local_paca->dtl_ridx != be64_to_cpu(lp->dtl_idx)))
0098             accumulate_stolen_time();
0099     }
0100 #endif
0101 }
0102 
0103 #endif /* __KERNEL__ */
0104 #else /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
0105 static inline void account_cpu_user_entry(void)
0106 {
0107 }
0108 static inline void account_cpu_user_exit(void)
0109 {
0110 }
0111 static notrace inline void account_stolen_time(void)
0112 {
0113 }
0114 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
0115 #endif /* __POWERPC_CPUTIME_H */