0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifndef _VMWGFX_MKSSTAT_H_
0029 #define _VMWGFX_MKSSTAT_H_
0030
0031 #include <asm/page.h>
0032
0033
0034 #define MKSSTAT_PID_RESERVED -1
0035
0036 #if IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS)
0037
0038
0039
0040
0041
0042 typedef enum {
0043 MKSSTAT_KERN_EXECBUF,
0044
0045 MKSSTAT_KERN_COUNT
0046 } mksstat_kern_stats_t;
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 static inline void *vmw_mksstat_get_kern_pstat(void *page_addr)
0057 {
0058 return page_addr + PAGE_SIZE * 1;
0059 }
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 static inline void *vmw_mksstat_get_kern_pinfo(void *page_addr)
0070 {
0071 return page_addr + PAGE_SIZE * 2;
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 static inline void *vmw_mksstat_get_kern_pstrs(void *page_addr)
0083 {
0084 return page_addr + PAGE_SIZE * 3;
0085 }
0086
0087
0088
0089
0090
0091 struct mksstat_timer_t {
0092 mksstat_kern_stats_t old_top;
0093 const u64 t0;
0094 const int slot;
0095 };
0096
0097 #define MKS_STAT_TIME_DECL(kern_cntr) \
0098 struct mksstat_timer_t _##kern_cntr = { \
0099 .t0 = rdtsc(), \
0100 .slot = vmw_mksstat_get_kern_slot(current->pid, dev_priv) \
0101 }
0102
0103 #define MKS_STAT_TIME_PUSH(kern_cntr) \
0104 do { \
0105 if (_##kern_cntr.slot >= 0) { \
0106 _##kern_cntr.old_top = dev_priv->mksstat_kern_top_timer[_##kern_cntr.slot]; \
0107 dev_priv->mksstat_kern_top_timer[_##kern_cntr.slot] = kern_cntr; \
0108 } \
0109 } while (0)
0110
0111 #define MKS_STAT_TIME_POP(kern_cntr) \
0112 do { \
0113 if (_##kern_cntr.slot >= 0) { \
0114 const pid_t pid = atomic_cmpxchg(&dev_priv->mksstat_kern_pids[_##kern_cntr.slot], current->pid, MKSSTAT_PID_RESERVED); \
0115 dev_priv->mksstat_kern_top_timer[_##kern_cntr.slot] = _##kern_cntr.old_top; \
0116 \
0117 if (pid == current->pid) { \
0118 const u64 dt = rdtsc() - _##kern_cntr.t0; \
0119 MKSGuestStatCounterTime *pstat; \
0120 \
0121 BUG_ON(!dev_priv->mksstat_kern_pages[_##kern_cntr.slot]); \
0122 \
0123 pstat = vmw_mksstat_get_kern_pstat(page_address(dev_priv->mksstat_kern_pages[_##kern_cntr.slot])); \
0124 \
0125 atomic64_inc(&pstat[kern_cntr].counter.count); \
0126 atomic64_add(dt, &pstat[kern_cntr].selfCycles); \
0127 atomic64_add(dt, &pstat[kern_cntr].totalCycles); \
0128 \
0129 if (_##kern_cntr.old_top != MKSSTAT_KERN_COUNT) \
0130 atomic64_sub(dt, &pstat[_##kern_cntr.old_top].selfCycles); \
0131 \
0132 atomic_set(&dev_priv->mksstat_kern_pids[_##kern_cntr.slot], current->pid); \
0133 } \
0134 } \
0135 } while (0)
0136
0137 #else
0138 #define MKS_STAT_TIME_DECL(kern_cntr)
0139 #define MKS_STAT_TIME_PUSH(kern_cntr)
0140 #define MKS_STAT_TIME_POP(kern_cntr)
0141
0142 #endif
0143
0144 #endif