Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
0002 /**************************************************************************
0003  *
0004  * Copyright 2021 VMware, Inc., Palo Alto, CA., USA
0005  *
0006  * Permission is hereby granted, free of charge, to any person obtaining a
0007  * copy of this software and associated documentation files (the
0008  * "Software"), to deal in the Software without restriction, including
0009  * without limitation the rights to use, copy, modify, merge, publish,
0010  * distribute, sub license, and/or sell copies of the Software, and to
0011  * permit persons to whom the Software is furnished to do so, subject to
0012  * the following conditions:
0013  *
0014  * The above copyright notice and this permission notice (including the
0015  * next paragraph) shall be included in all copies or substantial portions
0016  * of the Software.
0017  *
0018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0020  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
0021  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
0022  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0023  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0024  * USE OR OTHER DEALINGS IN THE SOFTWARE.
0025  *
0026  **************************************************************************/
0027 
0028 #ifndef _VMWGFX_MKSSTAT_H_
0029 #define _VMWGFX_MKSSTAT_H_
0030 
0031 #include <asm/page.h>
0032 
0033 /* Reservation marker for mksstat pid's */
0034 #define MKSSTAT_PID_RESERVED -1
0035 
0036 #if IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS)
0037 /*
0038  * Kernel-internal mksGuestStat counters. The order of this enum dictates the
0039  * order of instantiation of these counters in the mksGuestStat pages.
0040  */
0041 
0042 typedef enum {
0043     MKSSTAT_KERN_EXECBUF, /* vmw_execbuf_ioctl */
0044 
0045     MKSSTAT_KERN_COUNT /* Reserved entry; always last */
0046 } mksstat_kern_stats_t;
0047 
0048 /**
0049  * vmw_mksstat_get_kern_pstat: Computes the address of the MKSGuestStatCounterTime
0050  * array from the address of the base page.
0051  *
0052  * @page_addr: Pointer to the base page.
0053  * Return: Pointer to the MKSGuestStatCounterTime array.
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  * vmw_mksstat_get_kern_pinfo: Computes the address of the MKSGuestStatInfoEntry
0063  * array from the address of the base page.
0064  *
0065  * @page_addr: Pointer to the base page.
0066  * Return: Pointer to the MKSGuestStatInfoEntry array.
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  * vmw_mksstat_get_kern_pstrs: Computes the address of the mksGuestStat strings
0076  * sequence from the address of the base page.
0077  *
0078  * @page_addr: Pointer to the base page.
0079  * Return: Pointer to the mksGuestStat strings sequence.
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  * MKS_STAT_TIME_DECL/PUSH/POP macros to be used in timer-counted routines.
0089  */
0090 
0091 struct mksstat_timer_t {
0092 /* mutable */ 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 /* IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS */
0143 
0144 #endif