1 /*************************************************************************/ /*!
3 @Title Process based statistics
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Manages a collection of statistics based around a process
6 and referenced via OS agnostic methods.
7 @License Dual MIT/GPLv2
9 The contents of this file are subject to the MIT license as set out below.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
33 This License is also included in this distribution in the file called
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
48 #include "img_types.h"
49 #include "pvr_debug.h"
54 #include "process_stats.h"
55 #include "ri_server.h"
57 #include "connection_server.h"
60 #define DBGTIMEDIFF(T0, T1) ((IMG_UINT64) ( (T0) <= (T1) ? (T1) - (T0): IMG_UINT64_MAX - (T0) + (T1) ))
61 #define MEAN_TIME(A, B) ( ((3*(A))/4) + ((1 * (B))/4) )
65 * Maximum history of process statistics that will be kept.
67 #define MAX_DEAD_LIST_PROCESSES (10)
69 void *pvOSPowerStatsEntryData=NULL;
73 * Definition of all process based statistics and the strings used to
78 /* Stats that are per process... */
79 PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS,
80 PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS,
82 PVRSRV_PROCESS_STAT_TYPE_RC_OOMS,
83 PVRSRV_PROCESS_STAT_TYPE_RC_PRS,
84 PVRSRV_PROCESS_STAT_TYPE_RC_GROWS,
85 PVRSRV_PROCESS_STAT_TYPE_RC_PUSH_GROWS,
86 PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES,
87 PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES,
88 PVRSRV_PROCESS_STAT_TYPE_RC_SH_STORES,
89 PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES,
90 PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP,
91 PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW,
92 PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP,
93 PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW,
94 PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT,
95 PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES,
96 PVRSRV_PROCESS_STAT_TYPE_KMALLOC,
97 PVRSRV_PROCESS_STAT_TYPE_KMALLOC_MAX,
98 PVRSRV_PROCESS_STAT_TYPE_VMALLOC,
99 PVRSRV_PROCESS_STAT_TYPE_VMALLOC_MAX,
100 PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA,
101 PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA_MAX,
102 PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA,
103 PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA_MAX,
104 PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA,
105 PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA_MAX,
106 PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA,
107 PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA_MAX,
108 PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES,
109 PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES_MAX,
110 PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES,
111 PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES_MAX,
112 PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES,
113 PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES_MAX,
115 //zxl: count total data
116 PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC,
117 PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC,
118 PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP,
119 PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP,
121 /* Must be the last enum...*/
122 PVRSRV_PROCESS_STAT_TYPE_COUNT
123 } PVRSRV_PROCESS_STAT_TYPE;
128 PVRSRV_POWER_TIMING_STAT_FORCED_POWER_TRANSITION=0,
129 PVRSRV_POWER_TIMING_STAT_PRE_DEVICE,
130 PVRSRV_POWER_TIMING_STAT_PRE_SYSTEM,
131 PVRSRV_POWER_TIMING_STAT_POST_DEVICE,
132 PVRSRV_POWER_TIMING_STAT_POST_SYSTEM,
133 PVRSRV_POWER_TIMING_STAT_NEWLINE1,
134 PVRSRV_POWER_TIMING_STAT_NOT_FORCED_POWER_TRANSITION,
135 PVRSRV_POWER_TIMING_STAT_NON_PRE_DEVICE,
136 PVRSRV_POWER_TIMING_STAT_NON_PRE_SYSTEM,
137 PVRSRV_POWER_TIMING_STAT_NON_POST_DEVICE,
138 PVRSRV_POWER_TIMING_STAT_NON_POST_SYSTEM,
139 PVRSRV_POWER_TIMING_STAT_NEWLINE2,
140 PVRSRV_POWER_TIMING_STAT_FW_BOOTUP_TIME,
141 PVRSRV_POWER_TIMING_STAT_HOST_ACK
142 } PVR_SRV_OTHER_STAT_TYPE;
145 static IMG_CHAR* pszProcessStatFmt[PVRSRV_PROCESS_STAT_TYPE_COUNT] = {
146 "Connections %10d\n", /* PVRSRV_STAT_TYPE_CONNECTIONS */
147 "ConnectionsMax %10d\n", /* PVRSRV_STAT_TYPE_MAXCONNECTIONS */
149 "RenderContextOutOfMemoryEvents %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_OOMS */
150 "RenderContextPartialRenders %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_PRS */
151 "RenderContextGrows %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_GROWS */
152 "RenderContextPushGrows %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_PUSH_GROWS */
153 "RenderContextTAStores %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES */
154 "RenderContext3DStores %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES */
155 "RenderContextSHStores %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_SH_STORES */
156 "RenderContextCDMStores %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES */
157 "ZSBufferRequestsByApp %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP */
158 "ZSBufferRequestsByFirmware %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW */
159 "FreeListGrowRequestsByApp %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP */
160 "FreeListGrowRequestsByFirmware %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW */
161 "FreeListInitialPages %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT */
162 "FreeListMaxPages %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES */
163 "MemoryUsageKMalloc %10d\n", /* PVRSRV_STAT_TYPE_KMALLOC */
164 "MemoryUsageKMallocMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_KMALLOC */
165 "MemoryUsageVMalloc %10d\n", /* PVRSRV_STAT_TYPE_VMALLOC */
166 "MemoryUsageVMallocMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_VMALLOC */
167 "MemoryUsageAllocPTMemoryUMA %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_PAGES_PT_UMA */
168 "MemoryUsageAllocPTMemoryUMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_PAGES_PT_UMA */
169 "MemoryUsageVMapPTUMA %10d\n", /* PVRSRV_STAT_TYPE_VMAP_PT_UMA */
170 "MemoryUsageVMapPTUMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_VMAP_PT_UMA */
171 "MemoryUsageAllocPTMemoryLMA %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_PAGES_PT_LMA */
172 "MemoryUsageAllocPTMemoryLMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_PAGES_PT_LMA */
173 "MemoryUsageIORemapPTLMA %10d\n", /* PVRSRV_STAT_TYPE_IOREMAP_PT_LMA */
174 "MemoryUsageIORemapPTLMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_IOREMAP_PT_LMA */
175 "MemoryUsageAllocGPUMemLMA %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_LMA_PAGES */
176 "MemoryUsageAllocGPUMemLMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_LMA_PAGES */
177 "MemoryUsageAllocGPUMemUMA %10d\n", /* PVRSRV_STAT_TYPE_ALLOC_UMA_PAGES */
178 "MemoryUsageAllocGPUMemUMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_ALLOC_UMA_PAGES */
179 "MemoryUsageMappedGPUMemUMA/LMA %10d\n", /* PVRSRV_STAT_TYPE_MAP_UMA_LMA_PAGES */
180 "MemoryUsageMappedGPUMemUMA/LMAMax %10d\n", /* PVRSRV_STAT_TYPE_MAX_MAP_UMA_LMA_PAGES */
182 //zxl: count total data
183 "MemoryUsageTotalAlloc %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC */
184 "MemoryUsageTotalAllocMax %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC */
185 "MemoryUsageTotalMap %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP */
186 "MemoryUsageTotalMapMax %10d\n", /* PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP */
191 * Functions for printing the information stored...
193 IMG_VOID ProcessStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
194 OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
196 IMG_VOID MemStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
197 OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
199 IMG_VOID RIMemStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
200 OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
202 IMG_VOID PowerStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
203 OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
205 IMG_VOID GlobalStatsPrintElements(IMG_PVOID pvFilePtr, IMG_PVOID pvStatPtr,
206 OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf);
211 * Macros for updating stat values.
213 #define UPDATE_MAX_VALUE(a,b) do { if ((b) > (a)) {(a) = (b);} } while(0)
214 #define INCREASE_STAT_VALUE(ptr,var,val) do { (ptr)->i32StatValue[(var)] += (val); if ((ptr)->i32StatValue[(var)] > (ptr)->i32StatValue[(var##_MAX)]) {(ptr)->i32StatValue[(var##_MAX)] = (ptr)->i32StatValue[(var)];} } while(0)
215 #define DECREASE_STAT_VALUE(ptr,var,val) do { if ((IMG_SIZE_T)(ptr)->i32StatValue[(var)] >= (val)) { (ptr)->i32StatValue[(var)] -= (val); } else { (ptr)->i32StatValue[(var)] = 0; } } while(0)
216 #define INCREASE_GLOBAL_STAT_VALUE(var,val) do { (var) += (val); if ((var) > (var##Max)) {(var##Max) = (var);} } while(0)
217 #define DECREASE_GLOBAL_STAT_VALUE(var,val) do { if ((var) >= (val)) { (var) -= (val); } else { (var) = 0; } } while(0)
221 * Structures for holding statistics...
225 PVRSRV_STAT_STRUCTURE_PROCESS = 1,
226 PVRSRV_STAT_STRUCTURE_RENDER_CONTEXT = 2,
227 PVRSRV_STAT_STRUCTURE_MEMORY = 3,
228 PVRSRV_STAT_STRUCTURE_RIMEMORY = 4
229 } PVRSRV_STAT_STRUCTURE_TYPE;
231 #define MAX_PROC_NAME_LENGTH (32)
233 typedef struct _PVRSRV_PROCESS_STATS_ {
234 /* Structure type (must be first!) */
235 PVRSRV_STAT_STRUCTURE_TYPE eStructureType;
237 /* Linked list pointers */
238 struct _PVRSRV_PROCESS_STATS_* psNext;
239 struct _PVRSRV_PROCESS_STATS_* psPrev;
241 /* OS level process ID */
243 IMG_UINT32 ui32RefCount;
244 IMG_UINT32 ui32MemRefCount;
246 /* Folder name used to store the statistic */
247 IMG_CHAR szFolderName[MAX_PROC_NAME_LENGTH];
249 /* OS specific data */
250 IMG_PVOID pvOSPidFolderData;
251 IMG_PVOID pvOSPidEntryData;
254 IMG_INT32 i32StatValue[PVRSRV_PROCESS_STAT_TYPE_COUNT];
256 /* Other statistics structures */
257 struct _PVRSRV_RENDER_STATS_* psRenderLiveList;
258 struct _PVRSRV_RENDER_STATS_* psRenderDeadList;
260 struct _PVRSRV_MEMORY_STATS_* psMemoryStats;
261 struct _PVRSRV_RI_MEMORY_STATS_* psRIMemoryStats;
262 } PVRSRV_PROCESS_STATS;
264 typedef struct _PVRSRV_RENDER_STATS_ {
265 /* Structure type (must be first!) */
266 PVRSRV_STAT_STRUCTURE_TYPE eStructureType;
268 /* Linked list pointers */
269 struct _PVRSRV_RENDER_STATS_* psNext;
270 struct _PVRSRV_RENDER_STATS_* psPrev;
272 /* OS specific data */
276 IMG_INT32 i32StatValue[4];
277 } PVRSRV_RENDER_STATS;
279 typedef struct _PVRSRV_MEM_ALLOC_REC_
281 PVRSRV_MEM_ALLOC_TYPE eAllocType;
283 IMG_VOID *pvCpuVAddr;
284 IMG_CPU_PHYADDR sCpuPAddr;
286 IMG_PVOID pvPrivateData;
288 struct _PVRSRV_MEM_ALLOC_REC_ *psNext;
289 struct _PVRSRV_MEM_ALLOC_REC_ **ppsThis;
290 } PVRSRV_MEM_ALLOC_REC;
292 typedef struct _PVRSRV_MEMORY_STATS_ {
293 /* Structure type (must be first!) */
294 PVRSRV_STAT_STRUCTURE_TYPE eStructureType;
296 /* OS specific data */
297 IMG_PVOID pvOSMemEntryData;
300 PVRSRV_MEM_ALLOC_REC *psMemoryRecords;
301 } PVRSRV_MEMORY_STATS;
303 typedef struct _PVRSRV_RI_MEMORY_STATS_ {
304 /* Structure type (must be first!) */
305 PVRSRV_STAT_STRUCTURE_TYPE eStructureType;
307 /* OS level process ID */
310 /* OS specific data */
311 IMG_PVOID pvOSRIMemEntryData;
312 } PVRSRV_RI_MEMORY_STATS;
314 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
315 static IMPLEMENT_LIST_INSERT(PVRSRV_MEM_ALLOC_REC)
316 static IMPLEMENT_LIST_REMOVE(PVRSRV_MEM_ALLOC_REC)
321 * Global Boolean to flag when the statistics are ready to monitor
322 * memory allocations.
324 static IMG_BOOL bProcessStatsInitialised = IMG_FALSE;
327 * Linked lists for process stats. Live stats are for processes which are still running
328 * and the dead list holds those that have exited.
330 static PVRSRV_PROCESS_STATS* psLiveList = IMG_NULL;
331 static PVRSRV_PROCESS_STATS* psDeadList = IMG_NULL;
333 POS_LOCK psLinkedListLock = IMG_NULL;
337 * Pointer to OS folder to hold PID folders.
339 IMG_CHAR* pszOSLivePidFolderName = "pid";
340 IMG_CHAR* pszOSDeadPidFolderName = "pids_retired";
341 IMG_PVOID pvOSLivePidFolder = IMG_NULL;
342 IMG_PVOID pvOSDeadPidFolder = IMG_NULL;
344 /* global driver-data folders */
345 typedef struct _GLOBAL_STATS_
347 IMG_UINT32 ui32MemoryUsageKMalloc;
348 IMG_UINT32 ui32MemoryUsageKMallocMax;
349 IMG_UINT32 ui32MemoryUsageVMalloc;
350 IMG_UINT32 ui32MemoryUsageVMallocMax;
351 IMG_UINT32 ui32MemoryUsageAllocPTMemoryUMA;
352 IMG_UINT32 ui32MemoryUsageAllocPTMemoryUMAMax;
353 IMG_UINT32 ui32MemoryUsageVMapPTUMA;
354 IMG_UINT32 ui32MemoryUsageVMapPTUMAMax;
355 IMG_UINT32 ui32MemoryUsageAllocPTMemoryLMA;
356 IMG_UINT32 ui32MemoryUsageAllocPTMemoryLMAMax;
357 IMG_UINT32 ui32MemoryUsageIORemapPTLMA;
358 IMG_UINT32 ui32MemoryUsageIORemapPTLMAMax;
359 IMG_UINT32 ui32MemoryUsageAllocGPUMemLMA;
360 IMG_UINT32 ui32MemoryUsageAllocGPUMemLMAMax;
361 IMG_UINT32 ui32MemoryUsageAllocGPUMemUMA;
362 IMG_UINT32 ui32MemoryUsageAllocGPUMemUMAMax;
363 IMG_UINT32 ui32MemoryUsageAllocGPUMemUMAPool;
364 IMG_UINT32 ui32MemoryUsageAllocGPUMemUMAPoolMax;
365 IMG_UINT32 ui32MemoryUsageMappedGPUMemUMA_LMA;
366 IMG_UINT32 ui32MemoryUsageMappedGPUMemUMA_LMAMax;
368 //zxl: count total data
369 IMG_UINT32 ui32MemoryUsageTotalAlloc;
370 IMG_UINT32 ui32MemoryUsageTotalAllocMax;
371 IMG_UINT32 ui32MemoryUsageTotalMap;
372 IMG_UINT32 ui32MemoryUsageTotalMapMax;
375 static IMG_PVOID pvOSGlobalMemEntryRef = IMG_NULL;
376 static IMG_CHAR* const pszDriverStatFilename = "driver_stats";
377 static GLOBAL_STATS gsGlobalStats;
379 #define HASH_INITIAL_SIZE 5
380 /* A hash table used to store the size of any vmalloc'd allocation
381 * against its address (not needed for kmallocs as we can use ksize()) */
382 static HASH_TABLE* gpsVmallocSizeHashTable;
383 static POS_LOCK gpsVmallocSizeHashTableLock;
385 /*Power Statistics List */
387 static IMG_UINT64 ui64TotalForcedEntries=0,ui64TotalNotForcedEntries=0;
389 static IMG_UINT64 ui64ForcedPreDevice=0, ui64ForcedPreSystem=0, ui64ForcedPostDevice=0, ui64ForcedPostSystem=0;
390 static IMG_UINT64 ui64NotForcedPreDevice=0, ui64NotForcedPreSystem=0, ui64NotForcedPostDevice=0, ui64NotForcedPostSystem=0;
392 static IMG_UINT32 _PVRSRVIncrMemStatRefCount(IMG_PVOID pvStatPtr);
393 static IMG_UINT32 _PVRSRVDecrMemStatRefCount(IMG_PVOID pvStatPtr);
395 IMG_VOID InsertPowerTimeStatistic(PVRSRV_POWER_ENTRY_TYPE bType,
396 IMG_INT32 i32CurrentState, IMG_INT32 i32NextState,
397 IMG_UINT64 ui64SysStartTime, IMG_UINT64 ui64SysEndTime,
398 IMG_UINT64 ui64DevStartTime, IMG_UINT64 ui64DevEndTime,
401 IMG_UINT64 ui64Device;
402 IMG_UINT64 ui64System;
404 if (i32CurrentState==i32NextState) return ;
406 ui64Device=ui64DevEndTime-ui64DevStartTime;
407 ui64System=ui64SysEndTime-ui64SysStartTime;
411 ui64TotalForcedEntries++;
412 if (bType==PVRSRV_POWER_ENTRY_TYPE_POST)
414 ui64ForcedPostDevice+=ui64Device;
415 ui64ForcedPostSystem+=ui64System;
419 ui64ForcedPreDevice+=ui64Device;
420 ui64ForcedPreSystem+=ui64System;
425 ui64TotalNotForcedEntries++;
426 if (bType==PVRSRV_POWER_ENTRY_TYPE_POST)
428 ui64NotForcedPostDevice+=ui64Device;
429 ui64NotForcedPostSystem+=ui64System;
433 ui64NotForcedPreDevice+=ui64Device;
434 ui64NotForcedPreSystem+=ui64System;
441 typedef struct _EXTRA_POWER_STATS_
443 IMG_UINT64 ui64PreClockSpeedChangeDuration;
444 IMG_UINT64 ui64BetweenPreEndingAndPostStartingDuration;
445 IMG_UINT64 ui64PostClockSpeedChangeDuration;
448 #define NUM_EXTRA_POWER_STATS 10
450 static EXTRA_POWER_STATS asClockSpeedChanges[NUM_EXTRA_POWER_STATS];
451 static IMG_UINT32 ui32ClockSpeedIndexStart = 0, ui32ClockSpeedIndexEnd = 0;
453 static IMG_UINT64 ui64PreClockSpeedChangeMark = 0;
455 IMG_VOID InsertPowerTimeStatisticExtraPre(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64Stoptimer)
457 asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64PreClockSpeedChangeDuration = ui64Stoptimer - ui64StartTimer;
459 ui64PreClockSpeedChangeMark = OSClockus();
464 IMG_VOID InsertPowerTimeStatisticExtraPost(IMG_UINT64 ui64StartTimer, IMG_UINT64 ui64StopTimer)
466 IMG_UINT64 ui64Duration = ui64StartTimer - ui64PreClockSpeedChangeMark;
468 PVR_ASSERT(ui64PreClockSpeedChangeMark > 0);
470 asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64BetweenPreEndingAndPostStartingDuration = ui64Duration;
471 asClockSpeedChanges[ui32ClockSpeedIndexEnd].ui64PostClockSpeedChangeDuration = ui64StopTimer - ui64StartTimer;
473 ui32ClockSpeedIndexEnd = (ui32ClockSpeedIndexEnd + 1) % NUM_EXTRA_POWER_STATS;
475 if (ui32ClockSpeedIndexEnd == ui32ClockSpeedIndexStart)
477 ui32ClockSpeedIndexStart = (ui32ClockSpeedIndexStart + 1) % NUM_EXTRA_POWER_STATS;
480 ui64PreClockSpeedChangeMark = 0;
485 /*************************************************************************/ /*!
486 @Function _RemoveRenderStatsFromList
487 @Description Detaches a process from either the live or dead list.
488 @Input psProcessStats Process to remove the stats from.
489 @Input psRenderStats Render stats to remove.
490 */ /**************************************************************************/
492 _RemoveRenderStatsFromList(PVRSRV_PROCESS_STATS* psProcessStats,
493 PVRSRV_RENDER_STATS* psRenderStats)
495 PVR_ASSERT(psProcessStats != IMG_NULL);
496 PVR_ASSERT(psRenderStats != IMG_NULL);
498 /* Remove the item from the linked lists... */
499 if (psProcessStats->psRenderLiveList == psRenderStats)
501 psProcessStats->psRenderLiveList = psRenderStats->psNext;
503 if (psProcessStats->psRenderLiveList != IMG_NULL)
505 psProcessStats->psRenderLiveList->psPrev = IMG_NULL;
508 else if (psProcessStats->psRenderDeadList == psRenderStats)
510 psProcessStats->psRenderDeadList = psRenderStats->psNext;
512 if (psProcessStats->psRenderDeadList != IMG_NULL)
514 psProcessStats->psRenderDeadList->psPrev = IMG_NULL;
519 PVRSRV_RENDER_STATS* psNext = psRenderStats->psNext;
520 PVRSRV_RENDER_STATS* psPrev = psRenderStats->psPrev;
522 if (psRenderStats->psNext != IMG_NULL)
524 psRenderStats->psNext->psPrev = psPrev;
526 if (psRenderStats->psPrev != IMG_NULL)
528 psRenderStats->psPrev->psNext = psNext;
532 /* Reset the pointers in this cell, as it is not attached to anything */
533 psRenderStats->psNext = IMG_NULL;
534 psRenderStats->psPrev = IMG_NULL;
535 } /* _RemoveRenderStatsFromList */
538 /*************************************************************************/ /*!
539 @Function _DestoryRenderStat
540 @Description Frees memory and resources held by a render statistic.
541 @Input psRenderStats Render stats to destroy.
542 */ /**************************************************************************/
544 _DestoryRenderStat(PVRSRV_RENDER_STATS* psRenderStats)
546 PVR_ASSERT(psRenderStats != IMG_NULL);
548 /* Remove the statistic from the OS... */
549 // OSRemoveStatisticEntry(psRenderStats->pvOSData);
551 /* Free the memory... */
552 OSFreeMem(psRenderStats);
553 } /* _DestoryRenderStat */
556 /*************************************************************************/ /*!
557 @Function _FindProcessStatsInLiveList
558 @Description Searches the Live Process List for a statistics structure that
559 matches the PID given.
560 @Input pid Process to search for.
561 @Return Pointer to stats structure for the process.
562 */ /**************************************************************************/
563 static PVRSRV_PROCESS_STATS*
564 _FindProcessStatsInLiveList(IMG_PID pid)
566 PVRSRV_PROCESS_STATS* psProcessStats = psLiveList;
568 while (psProcessStats != IMG_NULL)
570 if (psProcessStats->pid == pid)
572 return psProcessStats;
575 psProcessStats = psProcessStats->psNext;
579 } /* _FindProcessStatsInLiveList */
582 /*************************************************************************/ /*!
583 @Function _FindProcessStatsInDeadList
584 @Description Searches the Dead Process List for a statistics structure that
585 matches the PID given.
586 @Input pid Process to search for.
587 @Return Pointer to stats structure for the process.
588 */ /**************************************************************************/
589 static PVRSRV_PROCESS_STATS*
590 _FindProcessStatsInDeadList(IMG_PID pid)
592 PVRSRV_PROCESS_STATS* psProcessStats = psDeadList;
594 while (psProcessStats != IMG_NULL)
596 if (psProcessStats->pid == pid)
598 return psProcessStats;
601 psProcessStats = psProcessStats->psNext;
605 } /* _FindProcessStatsInDeadList */
608 /*************************************************************************/ /*!
609 @Function _FindProcessStats
610 @Description Searches the Live and Dead Process Lists for a statistics
611 structure that matches the PID given.
612 @Input pid Process to search for.
613 @Return Pointer to stats structure for the process.
614 */ /**************************************************************************/
615 static PVRSRV_PROCESS_STATS*
616 _FindProcessStats(IMG_PID pid)
618 PVRSRV_PROCESS_STATS* psProcessStats = _FindProcessStatsInLiveList(pid);
620 if (psProcessStats == IMG_NULL)
622 psProcessStats = _FindProcessStatsInDeadList(pid);
625 return psProcessStats;
626 } /* _FindProcessStats */
629 /*************************************************************************/ /*!
630 @Function _AddProcessStatsToFrontOfLiveList
631 @Description Add a statistic to the live list head.
632 @Input psProcessStats Process stats to add.
633 */ /**************************************************************************/
635 _AddProcessStatsToFrontOfLiveList(PVRSRV_PROCESS_STATS* psProcessStats)
637 PVR_ASSERT(psProcessStats != IMG_NULL);
639 if (psLiveList != IMG_NULL)
641 psLiveList->psPrev = psProcessStats;
642 psProcessStats->psNext = psLiveList;
645 psLiveList = psProcessStats;
646 } /* _AddProcessStatsToFrontOfLiveList */
649 /*************************************************************************/ /*!
650 @Function _AddProcessStatsToFrontOfDeadList
651 @Description Add a statistic to the dead list head.
652 @Input psProcessStats Process stats to add.
653 */ /**************************************************************************/
655 _AddProcessStatsToFrontOfDeadList(PVRSRV_PROCESS_STATS* psProcessStats)
657 PVR_ASSERT(psProcessStats != IMG_NULL);
659 if (psDeadList != IMG_NULL)
661 psDeadList->psPrev = psProcessStats;
662 psProcessStats->psNext = psDeadList;
665 psDeadList = psProcessStats;
666 } /* _AddProcessStatsToFrontOfDeadList */
669 /*************************************************************************/ /*!
670 @Function _RemoveProcessStatsFromList
671 @Description Detaches a process from either the live or dead list.
672 @Input psProcessStats Process stats to remove.
673 */ /**************************************************************************/
675 _RemoveProcessStatsFromList(PVRSRV_PROCESS_STATS* psProcessStats)
677 PVR_ASSERT(psProcessStats != IMG_NULL);
679 /* Remove the item from the linked lists... */
680 if (psLiveList == psProcessStats)
682 psLiveList = psProcessStats->psNext;
684 if (psLiveList != IMG_NULL)
686 psLiveList->psPrev = IMG_NULL;
689 else if (psDeadList == psProcessStats)
691 psDeadList = psProcessStats->psNext;
693 if (psDeadList != IMG_NULL)
695 psDeadList->psPrev = IMG_NULL;
700 PVRSRV_PROCESS_STATS* psNext = psProcessStats->psNext;
701 PVRSRV_PROCESS_STATS* psPrev = psProcessStats->psPrev;
703 if (psProcessStats->psNext != IMG_NULL)
705 psProcessStats->psNext->psPrev = psPrev;
707 if (psProcessStats->psPrev != IMG_NULL)
709 psProcessStats->psPrev->psNext = psNext;
713 /* Reset the pointers in this cell, as it is not attached to anything */
714 psProcessStats->psNext = IMG_NULL;
715 psProcessStats->psPrev = IMG_NULL;
716 } /* _RemoveProcessStatsFromList */
719 /*************************************************************************/ /*!
720 @Function _CreateOSStatisticEntries
721 @Description Create all OS entries for this statistic.
722 @Input psProcessStats Process stats to destroy.
723 @Input pvOSPidFolder Pointer to OS folder to place the entrys in.
724 */ /**************************************************************************/
726 _CreateOSStatisticEntries(PVRSRV_PROCESS_STATS* psProcessStats,
727 IMG_PVOID pvOSPidFolder)
729 PVR_ASSERT(psProcessStats != IMG_NULL);
731 psProcessStats->pvOSPidFolderData = OSCreateStatisticFolder(psProcessStats->szFolderName, pvOSPidFolder);
732 psProcessStats->pvOSPidEntryData = OSCreateStatisticEntry("process_stats",
733 psProcessStats->pvOSPidFolderData,
734 ProcessStatsPrintElements,
735 _PVRSRVIncrMemStatRefCount,
736 _PVRSRVDecrMemStatRefCount,
737 (IMG_PVOID) psProcessStats);
739 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
740 psProcessStats->psMemoryStats->pvOSMemEntryData = OSCreateStatisticEntry("mem_area",
741 psProcessStats->pvOSPidFolderData,
742 MemStatsPrintElements,
745 (IMG_PVOID) psProcessStats->psMemoryStats);
748 #if defined(PVR_RI_DEBUG)
749 psProcessStats->psRIMemoryStats->pvOSRIMemEntryData = OSCreateStatisticEntry("ri_mem_area",
750 psProcessStats->pvOSPidFolderData,
751 RIMemStatsPrintElements,
754 (IMG_PVOID) psProcessStats->psRIMemoryStats);
756 } /* _CreateOSStatisticEntries */
759 /*************************************************************************/ /*!
760 @Function _RemoveOSStatisticEntries
761 @Description Removed all OS entries used by this statistic.
762 @Input psProcessStats Process stats to destroy.
763 */ /**************************************************************************/
765 _RemoveOSStatisticEntries(PVRSRV_PROCESS_STATS* psProcessStats)
767 PVR_ASSERT(psProcessStats != IMG_NULL);
769 #if defined(PVR_RI_DEBUG)
770 OSRemoveStatisticEntry(psProcessStats->psRIMemoryStats->pvOSRIMemEntryData);
773 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
774 OSRemoveStatisticEntry(psProcessStats->psMemoryStats->pvOSMemEntryData);
777 if( psProcessStats->pvOSPidEntryData != IMG_NULL)
779 OSRemoveStatisticEntry(psProcessStats->pvOSPidEntryData);
781 if( psProcessStats->pvOSPidFolderData != IMG_NULL)
783 OSRemoveStatisticFolder(psProcessStats->pvOSPidFolderData);
785 } /* _RemoveOSStatisticEntries */
788 /*************************************************************************/ /*!
789 @Function _DestoryProcessStat
790 @Description Frees memory and resources held by a process statistic.
791 @Input psProcessStats Process stats to destroy.
792 */ /**************************************************************************/
794 _DestoryProcessStat(PVRSRV_PROCESS_STATS* psProcessStats)
796 PVR_ASSERT(psProcessStats != IMG_NULL);
798 /* Remove this statistic from the OS... */
799 //_RemoveOSStatisticEntries(psProcessStats);
801 /* Free the live and dead render statistic lists... */
802 while (psProcessStats->psRenderLiveList != IMG_NULL)
804 PVRSRV_RENDER_STATS* psRenderStats = psProcessStats->psRenderLiveList;
806 _RemoveRenderStatsFromList(psProcessStats, psRenderStats);
807 _DestoryRenderStat(psRenderStats);
810 while (psProcessStats->psRenderDeadList != IMG_NULL)
812 PVRSRV_RENDER_STATS* psRenderStats = psProcessStats->psRenderDeadList;
814 _RemoveRenderStatsFromList(psProcessStats, psRenderStats);
815 _DestoryRenderStat(psRenderStats);
818 /* Free the memory statistics... */
819 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
820 while (psProcessStats->psMemoryStats->psMemoryRecords)
822 List_PVRSRV_MEM_ALLOC_REC_Remove(psProcessStats->psMemoryStats->psMemoryRecords);
824 OSFreeMem(psProcessStats->psMemoryStats);
827 /* Free the memory... */
828 OSFreeMem(psProcessStats);
829 } /* _DestoryProcessStat */
831 static IMG_UINT32 _PVRSRVIncrMemStatRefCount(IMG_PVOID pvStatPtr)
833 PVRSRV_STAT_STRUCTURE_TYPE* peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
834 PVRSRV_PROCESS_STATS* psProcessStats = (PVRSRV_PROCESS_STATS*) pvStatPtr;
835 IMG_UINT32 ui32Res = 7777;
837 switch (*peStructureType)
839 case PVRSRV_STAT_STRUCTURE_PROCESS:
841 /* Increment stat memory refCount */
842 ui32Res = ++psProcessStats->ui32MemRefCount;
853 static IMG_UINT32 _PVRSRVDecrMemStatRefCount(IMG_PVOID pvStatPtr)
855 PVRSRV_STAT_STRUCTURE_TYPE* peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
856 PVRSRV_PROCESS_STATS* psProcessStats = (PVRSRV_PROCESS_STATS*) pvStatPtr;
857 IMG_UINT32 ui32Res = 7777;
859 switch (*peStructureType)
861 case PVRSRV_STAT_STRUCTURE_PROCESS:
863 /* Decrement stat memory refCount and free if now zero */
864 ui32Res = --psProcessStats->ui32MemRefCount;
867 _DestoryProcessStat(psProcessStats);
879 /*************************************************************************/ /*!
880 @Function _CompressMemoryUsage
881 @Description Reduces memory usage by deleting old statistics data.
882 This function requires that the list lock is not held!
883 */ /**************************************************************************/
885 _CompressMemoryUsage(IMG_VOID)
887 PVRSRV_PROCESS_STATS* psProcessStats;
888 PVRSRV_PROCESS_STATS* psProcessStatsToBeFreed;
889 IMG_UINT32 ui32ItemsRemaining;
892 * We hold the lock whilst checking the list, but we'll release it
893 * before freeing memory (as that will require the lock too)!
895 OSLockAcquire(psLinkedListLock);
897 /* Check that the dead list is not bigger than the max size... */
898 psProcessStats = psDeadList;
899 psProcessStatsToBeFreed = IMG_NULL;
900 ui32ItemsRemaining = MAX_DEAD_LIST_PROCESSES;
902 while (psProcessStats != IMG_NULL && ui32ItemsRemaining > 0)
904 ui32ItemsRemaining--;
905 if (ui32ItemsRemaining == 0)
907 /* This is the last allowed process, cut the linked list here! */
908 psProcessStatsToBeFreed = psProcessStats->psNext;
909 psProcessStats->psNext = IMG_NULL;
913 psProcessStats = psProcessStats->psNext;
917 OSLockRelease(psLinkedListLock);
919 /* Any processes stats remaining will need to be destroyed... */
920 while (psProcessStatsToBeFreed != IMG_NULL)
922 PVRSRV_PROCESS_STATS* psNextProcessStats = psProcessStatsToBeFreed->psNext;
924 psProcessStatsToBeFreed->psNext = IMG_NULL;
925 _RemoveOSStatisticEntries(psProcessStatsToBeFreed);
926 _PVRSRVDecrMemStatRefCount((void*)psProcessStatsToBeFreed);
927 //_DestoryProcessStat(psProcessStatsToBeFreed);
929 psProcessStatsToBeFreed = psNextProcessStats;
931 } /* _CompressMemoryUsage */
933 /* These functions move the process stats from the living to the dead list.
934 * _MoveProcessToDeadList moves the entry in the global lists and
935 * it needs to be protected by psLinkedListLock.
936 * _MoveProcessToDeadListDebugFS performs the OS calls and it
937 * shouldn't be used under psLinkedListLock because this could generate a
938 * lockdep warning. */
940 _MoveProcessToDeadList(PVRSRV_PROCESS_STATS* psProcessStats)
942 /* Take the element out of the live list and append to the dead list... */
943 _RemoveProcessStatsFromList(psProcessStats);
944 _AddProcessStatsToFrontOfDeadList(psProcessStats);
945 } /* _MoveProcessToDeadList */
948 _MoveProcessToDeadListDebugFS(PVRSRV_PROCESS_STATS* psProcessStats)
950 /* Transfer the OS entries to the folder for dead processes... */
951 _RemoveOSStatisticEntries(psProcessStats);
952 _CreateOSStatisticEntries(psProcessStats, pvOSDeadPidFolder);
953 } /* _MoveProcessToDeadListDebugFS */
956 /*************************************************************************/ /*!
957 @Function PVRSRVStatsInitialise
958 @Description Entry point for initialising the statistics module.
959 @Return Standard PVRSRV_ERROR error code.
960 */ /**************************************************************************/
962 PVRSRVStatsInitialise(IMG_VOID)
966 PVR_ASSERT(psLiveList == IMG_NULL);
967 PVR_ASSERT(psDeadList == IMG_NULL);
968 PVR_ASSERT(psLinkedListLock == IMG_NULL);
969 PVR_ASSERT(gpsVmallocSizeHashTable == NULL);
970 PVR_ASSERT(bProcessStatsInitialised == IMG_FALSE);
972 /* We need a lock to protect the linked lists... */
973 error = OSLockCreate(&psLinkedListLock, LOCK_TYPE_NONE);
974 if (error == PVRSRV_OK)
976 /* We also need a lock to protect the hash table used for vmalloc size tracking.. */
977 error = OSLockCreate(&gpsVmallocSizeHashTableLock, LOCK_TYPE_NONE);
979 if (error != PVRSRV_OK)
983 /* Create a pid folders for putting the PID files in... */
984 pvOSLivePidFolder = OSCreateStatisticFolder(pszOSLivePidFolderName, IMG_NULL);
985 pvOSDeadPidFolder = OSCreateStatisticFolder(pszOSDeadPidFolderName, IMG_NULL);
987 /* Create power stats entry... */
988 pvOSPowerStatsEntryData = OSCreateStatisticEntry("power_timing_stats",
990 PowerStatsPrintElements,
995 pvOSGlobalMemEntryRef = OSCreateStatisticEntry(pszDriverStatFilename,
997 GlobalStatsPrintElements,
1002 /* Flag that we are ready to start monitoring memory allocations. */
1004 gpsVmallocSizeHashTable = HASH_Create(HASH_INITIAL_SIZE);
1006 OSMemSet(&gsGlobalStats, 0, sizeof(gsGlobalStats));
1008 OSMemSet(asClockSpeedChanges, 0, sizeof(asClockSpeedChanges));
1010 bProcessStatsInitialised = IMG_TRUE;
1014 OSLockDestroy(psLinkedListLock);
1015 psLinkedListLock = NULL;
1018 } /* PVRSRVStatsInitialise */
1021 /*************************************************************************/ /*!
1022 @Function PVRSRVStatsDestroy
1023 @Description Method for destroying the statistics module data.
1024 */ /**************************************************************************/
1026 PVRSRVStatsDestroy(IMG_VOID)
1028 PVR_ASSERT(bProcessStatsInitialised == IMG_TRUE);
1030 /* Stop monitoring memory allocations... */
1031 bProcessStatsInitialised = IMG_FALSE;
1033 /* Destroy the power stats entry... */
1034 if (pvOSPowerStatsEntryData!=NULL)
1036 OSRemoveStatisticEntry(pvOSPowerStatsEntryData);
1037 pvOSPowerStatsEntryData=NULL;
1040 /* Destroy the global data entry */
1041 if (pvOSGlobalMemEntryRef!=NULL)
1043 OSRemoveStatisticEntry(pvOSGlobalMemEntryRef);
1044 pvOSGlobalMemEntryRef=NULL;
1047 /* Destroy the lock... */
1048 if (psLinkedListLock != IMG_NULL)
1050 OSLockDestroy(psLinkedListLock);
1051 psLinkedListLock = IMG_NULL;
1054 /* Free the live and dead lists... */
1055 while (psLiveList != IMG_NULL)
1057 PVRSRV_PROCESS_STATS* psProcessStats = psLiveList;
1059 _RemoveProcessStatsFromList(psProcessStats);
1060 _RemoveOSStatisticEntries(psProcessStats);
1063 while (psDeadList != IMG_NULL)
1065 PVRSRV_PROCESS_STATS* psProcessStats = psDeadList;
1067 _RemoveProcessStatsFromList(psProcessStats);
1068 _RemoveOSStatisticEntries(psProcessStats);
1071 /* Remove the OS folders used by the PID folders... */
1072 OSRemoveStatisticFolder(pvOSLivePidFolder);
1073 pvOSLivePidFolder = IMG_NULL;
1074 OSRemoveStatisticFolder(pvOSDeadPidFolder);
1075 pvOSDeadPidFolder = IMG_NULL;
1077 if (gpsVmallocSizeHashTable != IMG_NULL)
1079 HASH_Delete(gpsVmallocSizeHashTable);
1081 if (gpsVmallocSizeHashTableLock != IMG_NULL)
1083 OSLockDestroy(gpsVmallocSizeHashTableLock);
1084 gpsVmallocSizeHashTableLock = IMG_NULL;
1087 } /* PVRSRVStatsDestroy */
1091 static void _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1096 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
1097 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageKMalloc, uiBytes);
1100 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
1101 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMalloc, uiBytes);
1104 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
1105 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA, uiBytes);
1108 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
1109 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMapPTUMA, uiBytes);
1112 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
1113 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA, uiBytes);
1116 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
1117 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageIORemapPTLMA, uiBytes);
1120 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
1121 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA, uiBytes);
1124 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
1125 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA, uiBytes);
1128 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
1129 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA, uiBytes);
1132 case PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES:
1133 DECREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPool, uiBytes);
1142 static void _increase_global_stat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1147 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
1148 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageKMalloc, uiBytes);
1151 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
1152 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMalloc, uiBytes);
1155 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
1156 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA, uiBytes);
1159 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
1160 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageVMapPTUMA, uiBytes);
1163 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
1164 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA, uiBytes);
1167 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
1168 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageIORemapPTLMA, uiBytes);
1171 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
1172 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA, uiBytes);
1175 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
1176 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA, uiBytes);
1179 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
1180 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA, uiBytes);
1183 case PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES:
1184 INCREASE_GLOBAL_STAT_VALUE(gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPool, uiBytes);
1192 gsGlobalStats.ui32MemoryUsageTotalAlloc = gsGlobalStats.ui32MemoryUsageKMalloc + gsGlobalStats.ui32MemoryUsageVMalloc +\
1193 gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA + gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA +\
1194 gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA + gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA;
1196 gsGlobalStats.ui32MemoryUsageTotalMap = gsGlobalStats.ui32MemoryUsageVMapPTUMA + gsGlobalStats.ui32MemoryUsageIORemapPTLMA +\
1197 gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA;
1199 gsGlobalStats.ui32MemoryUsageTotalAlloc = gsGlobalStats.ui32MemoryUsageKMalloc + gsGlobalStats.ui32MemoryUsageVMalloc +\
1200 gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA + gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA +\
1201 gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA + gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA;
1202 UPDATE_MAX_VALUE(gsGlobalStats.ui32MemoryUsageTotalAllocMax,gsGlobalStats.ui32MemoryUsageTotalAlloc);
1204 gsGlobalStats.ui32MemoryUsageTotalMap = gsGlobalStats.ui32MemoryUsageVMapPTUMA + gsGlobalStats.ui32MemoryUsageIORemapPTLMA +\
1205 gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA;
1206 UPDATE_MAX_VALUE(gsGlobalStats.ui32MemoryUsageTotalMapMax,gsGlobalStats.ui32MemoryUsageTotalMap);
1210 /*************************************************************************/ /*!
1211 @Function PVRSRVStatsRegisterProcess
1212 @Description Register a process into the list statistics list.
1213 @Output phProcessStats Handle to the process to be used to deregister.
1214 @Return Standard PVRSRV_ERROR error code.
1215 */ /**************************************************************************/
1217 PVRSRVStatsRegisterProcess(IMG_HANDLE* phProcessStats)
1219 PVRSRV_PROCESS_STATS* psProcessStats;
1220 IMG_PID currentPid = OSGetCurrentProcessID();
1221 IMG_BOOL bMoveProcess = IMG_FALSE;
1223 PVR_ASSERT(phProcessStats != IMG_NULL);
1225 /* Check the PID has not already moved to the dead list... */
1226 OSLockAcquire(psLinkedListLock);
1227 psProcessStats = _FindProcessStatsInDeadList(currentPid);
1228 if (psProcessStats != IMG_NULL)
1230 /* Move it back onto the live list! */
1231 _RemoveProcessStatsFromList(psProcessStats);
1232 _AddProcessStatsToFrontOfLiveList(psProcessStats);
1234 /* we can perform the OS operation out of lock */
1235 bMoveProcess = IMG_TRUE;
1239 /* Check the PID is not already registered in the live list... */
1240 psProcessStats = _FindProcessStatsInLiveList(currentPid);
1243 /* If the PID is on the live list then just increment the ref count and return... */
1244 if (psProcessStats != IMG_NULL)
1246 psProcessStats->ui32RefCount++;
1247 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = psProcessStats->ui32RefCount;
1248 UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS],
1249 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS]);
1250 OSLockRelease(psLinkedListLock);
1252 *phProcessStats = psProcessStats;
1254 /* Check if we need to perform any OS operation */
1257 /* Transfer the OS entries back to the folder for live processes... */
1258 _RemoveOSStatisticEntries(psProcessStats);
1259 _CreateOSStatisticEntries(psProcessStats, pvOSLivePidFolder);
1264 OSLockRelease(psLinkedListLock);
1266 /* Allocate a new node structure and initialise it... */
1267 psProcessStats = OSAllocMem(sizeof(PVRSRV_PROCESS_STATS));
1268 if (psProcessStats == IMG_NULL)
1270 *phProcessStats = 0;
1271 return PVRSRV_ERROR_OUT_OF_MEMORY;
1274 OSMemSet(psProcessStats, 0, sizeof(PVRSRV_PROCESS_STATS));
1276 psProcessStats->eStructureType = PVRSRV_STAT_STRUCTURE_PROCESS;
1277 psProcessStats->pid = currentPid;
1278 psProcessStats->ui32RefCount = 1;
1279 psProcessStats->ui32MemRefCount = 1;
1281 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = 1;
1282 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_CONNECTIONS] = 1;
1284 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
1285 psProcessStats->psMemoryStats = OSAllocMem(sizeof(PVRSRV_MEMORY_STATS));
1286 if (psProcessStats->psMemoryStats == IMG_NULL)
1288 OSFreeMem(psProcessStats);
1289 *phProcessStats = 0;
1290 return PVRSRV_ERROR_OUT_OF_MEMORY;
1293 OSMemSet(psProcessStats->psMemoryStats, 0, sizeof(PVRSRV_MEMORY_STATS));
1294 psProcessStats->psMemoryStats->eStructureType = PVRSRV_STAT_STRUCTURE_MEMORY;
1297 #if defined(PVR_RI_DEBUG)
1298 psProcessStats->psRIMemoryStats = OSAllocMem(sizeof(PVRSRV_RI_MEMORY_STATS));
1299 if (psProcessStats->psRIMemoryStats == IMG_NULL)
1301 OSFreeMem(psProcessStats->psMemoryStats);
1302 OSFreeMem(psProcessStats);
1303 *phProcessStats = 0;
1304 return PVRSRV_ERROR_OUT_OF_MEMORY;
1307 OSMemSet(psProcessStats->psRIMemoryStats, 0, sizeof(PVRSRV_RI_MEMORY_STATS));
1308 psProcessStats->psRIMemoryStats->eStructureType = PVRSRV_STAT_STRUCTURE_RIMEMORY;
1309 psProcessStats->psRIMemoryStats->pid = currentPid;
1312 /* Add it to the live list... */
1313 OSLockAcquire(psLinkedListLock);
1314 _AddProcessStatsToFrontOfLiveList(psProcessStats);
1315 OSLockRelease(psLinkedListLock);
1317 /* Create the process stat in the OS... */
1318 OSSNPrintf(psProcessStats->szFolderName, sizeof(psProcessStats->szFolderName),
1320 _CreateOSStatisticEntries(psProcessStats, pvOSLivePidFolder);
1323 *phProcessStats = (IMG_HANDLE) psProcessStats;
1326 } /* PVRSRVStatsRegisterProcess */
1329 /*************************************************************************/ /*!
1330 @Function PVRSRVStatsDeregisterProcess
1331 @Input hProcessStats Handle to the process returned when registered.
1332 @Description Method for destroying the statistics module data.
1333 */ /**************************************************************************/
1335 PVRSRVStatsDeregisterProcess(IMG_HANDLE hProcessStats)
1337 IMG_BOOL bMoveProcess = IMG_FALSE;
1339 if (hProcessStats != 0)
1341 PVRSRV_PROCESS_STATS* psProcessStats = (PVRSRV_PROCESS_STATS*) hProcessStats;
1343 /* Lower the reference count, if zero then move it to the dead list */
1344 OSLockAcquire(psLinkedListLock);
1345 if (psProcessStats->ui32RefCount > 0)
1347 psProcessStats->ui32RefCount--;
1348 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_CONNECTIONS] = psProcessStats->ui32RefCount;
1350 if (psProcessStats->ui32RefCount == 0)
1352 _MoveProcessToDeadList(psProcessStats);
1353 bMoveProcess = IMG_TRUE;
1356 OSLockRelease(psLinkedListLock);
1358 /* The OS calls need to be performed without psLinkedListLock */
1359 if (bMoveProcess == IMG_TRUE)
1361 _MoveProcessToDeadListDebugFS(psProcessStats);
1364 /* Check if the dead list needs to be reduced */
1365 _CompressMemoryUsage();
1367 } /* PVRSRVStatsDeregisterProcess */
1371 PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1372 IMG_VOID *pvCpuVAddr,
1373 IMG_CPU_PHYADDR sCpuPAddr,
1375 IMG_PVOID pvPrivateData)
1377 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
1378 IMG_PID currentPid = OSGetCurrentProcessID();
1379 IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid();
1380 PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData();
1381 PVRSRV_MEM_ALLOC_REC* psRecord = IMG_NULL;
1382 PVRSRV_PROCESS_STATS* psProcessStats;
1383 PVRSRV_MEMORY_STATS* psMemoryStats;
1385 /* Don't do anything if we are not initialised or we are shutting down! */
1386 if (!bProcessStatsInitialised)
1392 * To prevent a recursive loop, we make the memory allocations
1393 * for our memstat records via OSAllocMemstatMem(), which does not try to
1394 * create a memstat record entry..
1397 /* Allocate the memory record... */
1398 psRecord = OSAllocMemstatMem(sizeof(PVRSRV_MEM_ALLOC_REC));
1399 if (psRecord == IMG_NULL)
1404 OSMemSet(psRecord, 0, sizeof(PVRSRV_MEM_ALLOC_REC));
1405 psRecord->eAllocType = eAllocType;
1406 psRecord->pvCpuVAddr = pvCpuVAddr;
1407 psRecord->sCpuPAddr.uiAddr = sCpuPAddr.uiAddr;
1408 psRecord->uiBytes = uiBytes;
1409 psRecord->pvPrivateData = pvPrivateData;
1411 /* Lock while we find the correct process... */
1412 OSLockAcquire(psLinkedListLock);
1414 _increase_global_stat(eAllocType, uiBytes);
1418 if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
1419 (currentCleanupPid != 0))
1421 psProcessStats = _FindProcessStats(currentCleanupPid);
1425 psProcessStats = _FindProcessStats(currentPid);
1430 psProcessStats = _FindProcessStats(currentPid);
1432 if (psProcessStats == IMG_NULL)
1434 OSLockRelease(psLinkedListLock);
1435 if (psRecord != IMG_NULL)
1437 OSFreeMemstatMem(psRecord);
1441 psMemoryStats = psProcessStats->psMemoryStats;
1443 /* Insert the memory record... */
1444 if (psRecord != IMG_NULL)
1446 List_PVRSRV_MEM_ALLOC_REC_Insert(&psMemoryStats->psMemoryRecords, psRecord);
1449 /* Update the memory watermarks... */
1452 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
1454 if (psRecord != IMG_NULL)
1456 if (pvCpuVAddr == IMG_NULL)
1460 psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
1462 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes);
1466 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
1468 if (psRecord != IMG_NULL)
1470 if (pvCpuVAddr == IMG_NULL)
1474 psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
1476 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, uiBytes);
1480 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
1482 if (psRecord != IMG_NULL)
1484 if (pvCpuVAddr == IMG_NULL)
1488 psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
1490 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, uiBytes);
1494 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
1496 if (psRecord != IMG_NULL)
1498 if (pvCpuVAddr == IMG_NULL)
1502 psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
1504 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, uiBytes);
1508 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
1510 if (psRecord != IMG_NULL)
1512 psRecord->ui64Key = sCpuPAddr.uiAddr;
1514 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, uiBytes);
1518 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
1520 if (psRecord != IMG_NULL)
1522 if (pvCpuVAddr == IMG_NULL)
1526 psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
1528 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, uiBytes);
1532 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
1534 if (psRecord != IMG_NULL)
1536 psRecord->ui64Key = sCpuPAddr.uiAddr;
1538 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, uiBytes);
1542 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
1544 if (psRecord != IMG_NULL)
1546 psRecord->ui64Key = sCpuPAddr.uiAddr;
1548 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, uiBytes);
1552 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
1554 if (psRecord != IMG_NULL)
1556 if (pvCpuVAddr == IMG_NULL)
1560 psRecord->ui64Key = (IMG_UINT64)(IMG_UINTPTR_T)pvCpuVAddr;
1562 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, uiBytes);
1574 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] += psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
1575 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
1576 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
1577 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
1578 UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC],
1579 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC]);
1581 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] += psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
1582 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
1583 UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP],
1584 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP]);
1586 OSLockRelease(psLinkedListLock);
1588 PVR_UNREFERENCED_PARAMETER(eAllocType);
1589 PVR_UNREFERENCED_PARAMETER(pvCpuVAddr);
1590 PVR_UNREFERENCED_PARAMETER(sCpuPAddr);
1591 PVR_UNREFERENCED_PARAMETER(uiBytes);
1592 PVR_UNREFERENCED_PARAMETER(pvPrivateData);
1594 } /* PVRSRVStatsAddMemAllocRecord */
1598 PVRSRVStatsRemoveMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1601 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
1602 IMG_PID currentPid = OSGetCurrentProcessID();
1603 IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid();
1604 PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData();
1605 PVRSRV_PROCESS_STATS* psProcessStats = IMG_NULL;
1606 PVRSRV_MEMORY_STATS* psMemoryStats = IMG_NULL;
1607 PVRSRV_MEM_ALLOC_REC* psRecord = IMG_NULL;
1608 IMG_BOOL bFound = IMG_FALSE;
1610 /* Don't do anything if we are not initialised or we are shutting down! */
1611 if (!bProcessStatsInitialised)
1616 /* Lock while we find the correct process and remove this record... */
1617 OSLockAcquire(psLinkedListLock);
1621 if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
1622 (currentCleanupPid != 0))
1624 psProcessStats = _FindProcessStats(currentCleanupPid);
1628 psProcessStats = _FindProcessStats(currentPid);
1633 psProcessStats = _FindProcessStats(currentPid);
1635 if (psProcessStats != IMG_NULL)
1637 psMemoryStats = psProcessStats->psMemoryStats;
1638 psRecord = psMemoryStats->psMemoryRecords;
1639 while (psRecord != IMG_NULL)
1641 if (psRecord->ui64Key == ui64Key && psRecord->eAllocType == eAllocType)
1647 psRecord = psRecord->psNext;
1651 /* If not found, we need to do a full search in case it was allocated to a different PID... */
1654 PVRSRV_PROCESS_STATS* psProcessStatsAlreadyChecked = psProcessStats;
1656 /* Search all live lists first... */
1657 psProcessStats = psLiveList;
1658 while (psProcessStats != IMG_NULL)
1660 if (psProcessStats != psProcessStatsAlreadyChecked)
1662 psMemoryStats = psProcessStats->psMemoryStats;
1663 psRecord = psMemoryStats->psMemoryRecords;
1664 while (psRecord != IMG_NULL)
1666 if (psRecord->ui64Key == ui64Key && psRecord->eAllocType == eAllocType)
1672 psRecord = psRecord->psNext;
1681 psProcessStats = psProcessStats->psNext;
1684 /* If not found, then search all dead lists next... */
1687 psProcessStats = psDeadList;
1688 while (psProcessStats != IMG_NULL)
1690 if (psProcessStats != psProcessStatsAlreadyChecked)
1692 psMemoryStats = psProcessStats->psMemoryStats;
1693 psRecord = psMemoryStats->psMemoryRecords;
1694 while (psRecord != IMG_NULL)
1696 if (psRecord->ui64Key == ui64Key && psRecord->eAllocType == eAllocType)
1702 psRecord = psRecord->psNext;
1711 psProcessStats = psProcessStats->psNext;
1716 /* Update the watermark and remove this record...*/
1719 _decrease_global_stat(eAllocType, psRecord->uiBytes);
1723 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
1725 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, psRecord->uiBytes);
1729 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
1731 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, psRecord->uiBytes);
1735 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
1737 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, psRecord->uiBytes);
1741 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
1743 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, psRecord->uiBytes);
1747 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
1749 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, psRecord->uiBytes);
1753 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
1755 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, psRecord->uiBytes);
1759 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
1761 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, psRecord->uiBytes);
1765 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
1767 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, psRecord->uiBytes);
1771 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
1773 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, psRecord->uiBytes);
1784 List_PVRSRV_MEM_ALLOC_REC_Remove(psRecord);
1787 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
1788 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
1789 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
1790 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
1792 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
1793 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
1795 OSLockRelease(psLinkedListLock);
1798 * Free the record outside the lock so we don't deadlock and so we
1799 * reduce the time the lock is held.
1801 if (psRecord != IMG_NULL)
1803 OSFreeMemstatMem(psRecord);
1806 PVR_UNREFERENCED_PARAMETER(eAllocType);
1807 PVR_UNREFERENCED_PARAMETER(ui64Key);
1809 } /* PVRSRVStatsRemoveMemAllocRecord */
1812 PVRSRVStatsIncrMemAllocStatAndTrack(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1814 IMG_UINT64 uiCpuVAddr)
1818 if (!bProcessStatsInitialised || (gpsVmallocSizeHashTable == NULL) )
1823 OSLockAcquire(gpsVmallocSizeHashTableLock);
1824 bRes = HASH_Insert(gpsVmallocSizeHashTable, uiCpuVAddr, uiBytes);
1825 OSLockRelease(gpsVmallocSizeHashTableLock);
1828 PVRSRVStatsIncrMemAllocStat(eAllocType, uiBytes);
1832 PVR_DPF((PVR_DBG_ERROR, "*** %s : @ line %d HASH_Insert() failed!!", __FUNCTION__, __LINE__));
1837 PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1840 IMG_PID currentPid = OSGetCurrentProcessID();
1841 IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid();
1842 PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData();
1843 PVRSRV_PROCESS_STATS* psProcessStats;
1845 /* Don't do anything if we are not initialised or we are shutting down! */
1846 if (!bProcessStatsInitialised)
1851 _increase_global_stat(eAllocType, uiBytes);
1853 OSLockAcquire(psLinkedListLock);
1857 if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
1858 (currentCleanupPid != 0))
1860 psProcessStats = _FindProcessStats(currentCleanupPid);
1864 psProcessStats = _FindProcessStats(currentPid);
1869 psProcessStats = _FindProcessStats(currentPid);
1872 if (psProcessStats != IMG_NULL)
1874 /* Update the memory watermarks... */
1877 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
1879 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes);
1883 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
1885 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, uiBytes);
1889 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
1891 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, uiBytes);
1895 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
1897 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, uiBytes);
1901 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
1903 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, uiBytes);
1907 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
1909 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, uiBytes);
1913 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
1915 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, uiBytes);
1919 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
1921 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, uiBytes);
1925 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
1927 INCREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, uiBytes);
1938 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
1939 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
1940 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
1941 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
1942 UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_ALLOC],
1943 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC]);
1945 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
1946 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
1947 UPDATE_MAX_VALUE(psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAX_TOTAL_MAP],
1948 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP]);
1951 OSLockRelease(psLinkedListLock);
1955 PVRSRVStatsDecrMemAllocStatAndUntrack(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1956 IMG_UINT64 uiCpuVAddr)
1960 if (!bProcessStatsInitialised || (gpsVmallocSizeHashTable == NULL) )
1965 OSLockAcquire(gpsVmallocSizeHashTableLock);
1966 uiBytes = HASH_Remove(gpsVmallocSizeHashTable, uiCpuVAddr);
1967 OSLockRelease(gpsVmallocSizeHashTableLock);
1969 PVRSRVStatsDecrMemAllocStat(eAllocType, uiBytes);
1973 PVRSRVStatsDecrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE eAllocType,
1976 IMG_PID currentPid = OSGetCurrentProcessID();
1977 IMG_PID currentCleanupPid = PVRSRVGetPurgeConnectionPid();
1978 PVRSRV_DATA* psPVRSRVData = PVRSRVGetPVRSRVData();
1979 PVRSRV_PROCESS_STATS* psProcessStats;
1981 /* Don't do anything if we are not initialised or we are shutting down! */
1982 if (!bProcessStatsInitialised)
1987 _decrease_global_stat(eAllocType, uiBytes);
1989 OSLockAcquire(psLinkedListLock);
1993 if ( (currentPid == psPVRSRVData->cleanupThreadPid) &&
1994 (currentCleanupPid != 0))
1996 psProcessStats = _FindProcessStats(currentCleanupPid);
2000 psProcessStats = _FindProcessStats(currentPid);
2005 psProcessStats = _FindProcessStats(currentPid);
2007 if (psProcessStats != IMG_NULL)
2009 /* Update the memory watermarks... */
2012 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC:
2014 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_KMALLOC, uiBytes);
2018 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC:
2020 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMALLOC, uiBytes);
2024 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA:
2026 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA, uiBytes);
2030 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA:
2032 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA, uiBytes);
2036 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA:
2038 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA, uiBytes);
2042 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA:
2044 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA, uiBytes);
2048 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES:
2050 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_LMA_PAGES, uiBytes);
2054 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES:
2056 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES, uiBytes);
2060 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES:
2062 DECREASE_STAT_VALUE(psProcessStats, PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES, uiBytes);
2073 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_ALLOC] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_KMALLOC] +\
2074 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMALLOC] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_UMA] +\
2075 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_PAGES_PT_LMA] + PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES +\
2076 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ALLOC_UMA_PAGES] + psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_MAP_UMA_LMA_PAGES];
2078 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_TOTAL_MAP] = psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_VMAP_PT_UMA] +\
2079 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_IOREMAP_PT_LMA];
2082 OSLockRelease(psLinkedListLock);
2085 /* For now we do not want to expose the global stats API
2086 * so we wrap it into this specific function for pooled pages.
2087 * As soon as we need to modify the global stats directly somewhere else
2088 * we want to replace these functions with more general ones.
2091 PVRSRVStatsIncrMemAllocPoolStat(IMG_SIZE_T uiBytes)
2093 _increase_global_stat(PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, uiBytes);
2097 PVRSRVStatsDecrMemAllocPoolStat(IMG_SIZE_T uiBytes)
2099 _decrease_global_stat(PVRSRV_MEM_ALLOC_TYPE_UMA_POOL_PAGES, uiBytes);
2103 PVRSRVStatsUpdateRenderContextStats(IMG_UINT32 ui32TotalNumPartialRenders,
2104 IMG_UINT32 ui32TotalNumOutOfMemory,
2105 IMG_UINT32 ui32NumTAStores,
2106 IMG_UINT32 ui32Num3DStores,
2107 IMG_UINT32 ui32NumSHStores,
2108 IMG_UINT32 ui32NumCDMStores,
2111 //IMG_PID currentPid = OSGetCurrentProcessID();
2112 IMG_PID pidCurrent=pidOwner;
2114 PVRSRV_PROCESS_STATS* psProcessStats;
2116 /* Don't do anything if we are not initialised or we are shutting down! */
2117 if (!bProcessStatsInitialised)
2122 /* Lock while we find the correct process and update the record... */
2123 OSLockAcquire(psLinkedListLock);
2125 psProcessStats = _FindProcessStats(pidCurrent);
2126 if (psProcessStats != IMG_NULL)
2128 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_PRS] += ui32TotalNumPartialRenders;
2129 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_OOMS] += ui32TotalNumOutOfMemory;
2130 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_TA_STORES] += ui32NumTAStores;
2131 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_3D_STORES] += ui32Num3DStores;
2132 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_SH_STORES] += ui32NumSHStores;
2133 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_RC_CDM_STORES]+= ui32NumCDMStores;
2137 PVR_DPF((PVR_DBG_WARNING, "PVRSRVStatsUpdateRenderContextStats: Null process. Pid=%d", pidCurrent));
2140 OSLockRelease(psLinkedListLock);
2141 } /* PVRSRVStatsUpdateRenderContextStats */
2145 PVRSRVStatsUpdateZSBufferStats(IMG_UINT32 ui32NumReqByApp,
2146 IMG_UINT32 ui32NumReqByFW,
2149 IMG_PID currentPid = (owner==0)?OSGetCurrentProcessID():owner;
2150 PVRSRV_PROCESS_STATS* psProcessStats;
2153 /* Don't do anything if we are not initialised or we are shutting down! */
2154 if (!bProcessStatsInitialised)
2159 /* Lock while we find the correct process and update the record... */
2160 OSLockAcquire(psLinkedListLock);
2162 psProcessStats = _FindProcessStats(currentPid);
2163 if (psProcessStats != IMG_NULL)
2165 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_APP] += ui32NumReqByApp;
2166 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_ZSBUFFER_REQS_BY_FW] += ui32NumReqByFW;
2169 OSLockRelease(psLinkedListLock);
2170 } /* PVRSRVStatsUpdateZSBufferStats */
2174 PVRSRVStatsUpdateFreelistStats(IMG_UINT32 ui32NumGrowReqByApp,
2175 IMG_UINT32 ui32NumGrowReqByFW,
2176 IMG_UINT32 ui32InitFLPages,
2177 IMG_UINT32 ui32NumHighPages,
2180 IMG_PID currentPid = (ownerPid!=0)?ownerPid:OSGetCurrentProcessID();
2181 PVRSRV_PROCESS_STATS* psProcessStats;
2183 /* Don't do anything if we are not initialised or we are shutting down! */
2184 if (!bProcessStatsInitialised)
2189 /* Lock while we find the correct process and update the record... */
2190 OSLockAcquire(psLinkedListLock);
2192 psProcessStats = _FindProcessStats(currentPid);
2194 if (psProcessStats != IMG_NULL)
2196 /* Avoid signed / unsigned mismatch which is flagged by some compilers */
2199 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_APP] += ui32NumGrowReqByApp;
2200 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_GROW_REQS_BY_FW] += ui32NumGrowReqByFW;
2202 a=psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT];
2203 b=(IMG_INT32)(ui32InitFLPages);
2204 UPDATE_MAX_VALUE(a, b);
2207 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT]=a;
2208 ui32InitFLPages=(IMG_UINT32)b;
2210 a=psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_MAX_PAGES];
2211 b=(IMG_INT32)ui32NumHighPages;
2213 UPDATE_MAX_VALUE(a, b);
2214 psProcessStats->i32StatValue[PVRSRV_PROCESS_STAT_TYPE_FREELIST_PAGES_INIT]=a;
2215 ui32InitFLPages=(IMG_UINT32)b;
2219 OSLockRelease(psLinkedListLock);
2220 } /* PVRSRVStatsUpdateFreelistStats */
2223 /*************************************************************************/ /*!
2224 @Function ProcessStatsPrintElements
2225 @Description Prints all elements for this process statistic record.
2226 @Input pvFilePtr Pointer to seq_file.
2227 @Input pvStatPtr Pointer to statistics structure.
2228 @Input pfnOSStatsPrintf Printf function to use for output.
2229 */ /**************************************************************************/
2231 ProcessStatsPrintElements(IMG_PVOID pvFilePtr,
2232 IMG_PVOID pvStatPtr,
2233 OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
2235 PVRSRV_STAT_STRUCTURE_TYPE* peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
2236 PVRSRV_PROCESS_STATS* psProcessStats = (PVRSRV_PROCESS_STATS*) pvStatPtr;
2237 IMG_UINT32 ui32StatNumber = 0;
2239 if (peStructureType == IMG_NULL || *peStructureType != PVRSRV_STAT_STRUCTURE_PROCESS)
2241 PVR_ASSERT(peStructureType != IMG_NULL && *peStructureType == PVRSRV_STAT_STRUCTURE_PROCESS);
2245 if (pfnOSStatsPrintf == NULL)
2250 /* Loop through all the values and print them... */
2251 while (ui32StatNumber < PVRSRV_PROCESS_STAT_TYPE_COUNT)
2253 if (psProcessStats->ui32MemRefCount > 0)
2255 pfnOSStatsPrintf(pvFilePtr, pszProcessStatFmt[ui32StatNumber], psProcessStats->i32StatValue[ui32StatNumber]);
2259 PVR_DPF((PVR_DBG_ERROR, "%s: Called with psProcessStats->ui32MemRefCount=%d", __FUNCTION__, psProcessStats->ui32MemRefCount));
2263 } /* ProcessStatsPrintElements */
2266 #if defined(PVRSRV_ENABLE_MEMORY_STATS)
2267 /*************************************************************************/ /*!
2268 @Function MemStatsPrintElements
2269 @Description Prints all elements for the memory statistic record.
2270 @Input pvFilePtr Pointer to seq_file.
2271 @Input pvStatPtr Pointer to statistics structure.
2272 @Input pfnOSStatsPrintf Printf function to use for output.
2273 */ /**************************************************************************/
2275 MemStatsPrintElements(IMG_PVOID pvFilePtr,
2276 IMG_PVOID pvStatPtr,
2277 OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
2279 PVRSRV_STAT_STRUCTURE_TYPE* peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
2280 PVRSRV_MEMORY_STATS* psMemoryStats = (PVRSRV_MEMORY_STATS*) pvStatPtr;
2281 IMG_UINT32 ui32VAddrFields = sizeof(IMG_VOID*)/sizeof(IMG_UINT32);
2282 IMG_UINT32 ui32PAddrFields = sizeof(IMG_CPU_PHYADDR)/sizeof(IMG_UINT32);
2283 PVRSRV_MEM_ALLOC_REC *psRecord;
2284 IMG_UINT32 ui32ItemNumber;
2286 if (peStructureType == IMG_NULL || *peStructureType != PVRSRV_STAT_STRUCTURE_MEMORY)
2288 PVR_ASSERT(peStructureType != IMG_NULL && *peStructureType == PVRSRV_STAT_STRUCTURE_MEMORY);
2292 if (pfnOSStatsPrintf == NULL)
2297 /* Write the header... */
2298 pfnOSStatsPrintf(pvFilePtr, "Type VAddress");
2299 for (ui32ItemNumber = 1; ui32ItemNumber < ui32VAddrFields; ui32ItemNumber++)
2301 pfnOSStatsPrintf(pvFilePtr, " ");
2304 pfnOSStatsPrintf(pvFilePtr, " PAddress");
2305 for (ui32ItemNumber = 1; ui32ItemNumber < ui32PAddrFields; ui32ItemNumber++)
2307 pfnOSStatsPrintf(pvFilePtr, " ");
2310 pfnOSStatsPrintf(pvFilePtr, " Size(bytes)\n");
2312 /* The lock has to be held whilst moving through the memory list... */
2313 OSLockAcquire(psLinkedListLock);
2314 psRecord = psMemoryStats->psMemoryRecords;
2316 while (psRecord != IMG_NULL)
2318 switch (psRecord->eAllocType)
2320 case PVRSRV_MEM_ALLOC_TYPE_KMALLOC: pfnOSStatsPrintf(pvFilePtr, "KMALLOC "); break;
2321 case PVRSRV_MEM_ALLOC_TYPE_VMALLOC: pfnOSStatsPrintf(pvFilePtr, "VMALLOC "); break;
2322 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_LMA: pfnOSStatsPrintf(pvFilePtr, "ALLOC_PAGES_PT_LMA "); break;
2323 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_PAGES_PT_UMA: pfnOSStatsPrintf(pvFilePtr, "ALLOC_PAGES_PT_UMA "); break;
2324 case PVRSRV_MEM_ALLOC_TYPE_IOREMAP_PT_LMA: pfnOSStatsPrintf(pvFilePtr, "IOREMAP_PT_LMA "); break;
2325 case PVRSRV_MEM_ALLOC_TYPE_VMAP_PT_UMA: pfnOSStatsPrintf(pvFilePtr, "VMAP_PT_UMA "); break;
2326 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_LMA_PAGES: pfnOSStatsPrintf(pvFilePtr, "ALLOC_LMA_PAGES "); break;
2327 case PVRSRV_MEM_ALLOC_TYPE_ALLOC_UMA_PAGES: pfnOSStatsPrintf(pvFilePtr, "ALLOC_UMA_PAGES "); break;
2328 case PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES: pfnOSStatsPrintf(pvFilePtr, "MAP_UMA_LMA_PAGES "); break;
2329 default: pfnOSStatsPrintf(pvFilePtr, "INVALID "); break;
2332 for (ui32ItemNumber = 0; ui32ItemNumber < ui32VAddrFields; ui32ItemNumber++)
2334 pfnOSStatsPrintf(pvFilePtr, "%08x", *(((IMG_UINT32*) &psRecord->pvCpuVAddr) + ui32VAddrFields - ui32ItemNumber - 1));
2336 pfnOSStatsPrintf(pvFilePtr, " ");
2338 for (ui32ItemNumber = 0; ui32ItemNumber < ui32PAddrFields; ui32ItemNumber++)
2340 pfnOSStatsPrintf(pvFilePtr, "%08x", *(((IMG_UINT32*) &psRecord->sCpuPAddr.uiAddr) + ui32PAddrFields - ui32ItemNumber - 1));
2343 pfnOSStatsPrintf(pvFilePtr, " %u\n", psRecord->uiBytes);
2345 /* Move to next record... */
2346 psRecord = psRecord->psNext;
2349 OSLockRelease(psLinkedListLock);
2350 } /* MemStatsPrintElements */
2354 #if defined(PVR_RI_DEBUG)
2355 /*************************************************************************/ /*!
2356 @Function RIMemStatsPrintElements
2357 @Description Prints all elements for the RI Memory record.
2358 @Input pvFilePtr Pointer to seq_file.
2359 @Input pvStatPtr Pointer to statistics structure.
2360 @Input pfnOSStatsPrintf Printf function to use for output.
2361 */ /**************************************************************************/
2363 RIMemStatsPrintElements(IMG_PVOID pvFilePtr,
2364 IMG_PVOID pvStatPtr,
2365 OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
2367 PVRSRV_STAT_STRUCTURE_TYPE *peStructureType = (PVRSRV_STAT_STRUCTURE_TYPE*) pvStatPtr;
2368 PVRSRV_RI_MEMORY_STATS *psRIMemoryStats = (PVRSRV_RI_MEMORY_STATS*) pvStatPtr;
2369 IMG_CHAR *pszStatFmtText = IMG_NULL;
2370 IMG_HANDLE *pRIHandle = IMG_NULL;
2372 if (peStructureType == IMG_NULL || *peStructureType != PVRSRV_STAT_STRUCTURE_RIMEMORY)
2374 PVR_ASSERT(peStructureType != IMG_NULL && *peStructureType == PVRSRV_STAT_STRUCTURE_RIMEMORY);
2378 if (pfnOSStatsPrintf == NULL)
2384 * Loop through the RI system to get each line of text.
2386 while (RIGetListEntryKM(psRIMemoryStats->pid,
2390 pfnOSStatsPrintf(pvFilePtr, "%s", pszStatFmtText);
2392 } /* RIMemStatsPrintElements */
2396 static IMG_UINT32 ui32FirmwareStartTimestamp=0;
2397 static IMG_UINT64 ui64FirmwareIdleDuration=0;
2399 /* Averaging each new value with the previous accumulated knowledge. There are many coefficients for that
2400 * (e.g.) 50 / 50 but i chose 75 / 25 meaning that previous knowledge affects the weighted average more
2401 * than any new knowledge. As time goes by though eventually the number converges to the most commonly used
2404 IMG_VOID SetFirmwareStartTime(IMG_UINT32 ui32Time)
2406 if (ui32FirmwareStartTimestamp > 0)
2408 ui32FirmwareStartTimestamp = MEAN_TIME(ui32FirmwareStartTimestamp, ui32Time);
2412 ui32FirmwareStartTimestamp = ui32Time;
2416 IMG_VOID SetFirmwareHandshakeIdleTime(IMG_UINT64 ui64Duration)
2418 if (ui64FirmwareIdleDuration > 0)
2420 ui64FirmwareIdleDuration = MEAN_TIME(ui64FirmwareIdleDuration, ui64Duration);
2424 ui64FirmwareIdleDuration = ui64Duration;
2429 IMG_VOID PowerStatsPrintElements(IMG_PVOID pvFilePtr,
2430 IMG_PVOID pvStatPtr,
2431 OS_STATS_PRINTF_FUNC* pfnOSStatsPrintf)
2435 PVR_UNREFERENCED_PARAMETER(pvStatPtr);
2437 if (pfnOSStatsPrintf == NULL)
2442 if (ui64TotalForcedEntries > 0)
2444 pfnOSStatsPrintf(pvFilePtr, "Forced Power Transition (nanoseconds):\n");
2445 pfnOSStatsPrintf(pvFilePtr, "Pre-Device: %u\n", (IMG_UINT32)(ui64ForcedPreDevice) / (IMG_UINT32)(ui64TotalForcedEntries));
2446 pfnOSStatsPrintf(pvFilePtr, "Pre-System: %u\n", (IMG_UINT32)(ui64ForcedPreSystem) / (IMG_UINT32)(ui64TotalForcedEntries));
2447 pfnOSStatsPrintf(pvFilePtr, "Post-Device: %u\n", (IMG_UINT32)(ui64ForcedPostDevice) / (IMG_UINT32)(ui64TotalForcedEntries));
2448 pfnOSStatsPrintf(pvFilePtr, "Post-System: %u\n", (IMG_UINT32)(ui64ForcedPostSystem) / (IMG_UINT32)(ui64TotalForcedEntries));
2449 pfnOSStatsPrintf(pvFilePtr, "\n");
2452 if (ui64TotalNotForcedEntries > 0)
2454 pfnOSStatsPrintf(pvFilePtr, "Not Forced Power Transition (nanoseconds):\n");
2455 pfnOSStatsPrintf(pvFilePtr, "Pre-Device: %u\n", (IMG_UINT32)(ui64NotForcedPreDevice) / (IMG_UINT32)(ui64TotalNotForcedEntries));
2456 pfnOSStatsPrintf(pvFilePtr, "Pre-System: %u\n", (IMG_UINT32)(ui64NotForcedPreSystem) / (IMG_UINT32)(ui64TotalNotForcedEntries));
2457 pfnOSStatsPrintf(pvFilePtr, "Post-Device: %u\n", (IMG_UINT32)(ui64NotForcedPostDevice) / (IMG_UINT32)(ui64TotalNotForcedEntries));
2458 pfnOSStatsPrintf(pvFilePtr, "Post-System: %u\n", (IMG_UINT32)(ui64NotForcedPostSystem) / (IMG_UINT32)(ui64TotalNotForcedEntries));
2459 pfnOSStatsPrintf(pvFilePtr, "\n");
2462 pfnOSStatsPrintf(pvFilePtr, "FW bootup time (timer ticks): %u\n", ui32FirmwareStartTimestamp);
2463 pfnOSStatsPrintf(pvFilePtr, "Host Acknowledge Time for FW Idle Signal (timer ticks): %u\n", (IMG_UINT32)(ui64FirmwareIdleDuration));
2464 pfnOSStatsPrintf(pvFilePtr, "\n");
2466 pfnOSStatsPrintf(pvFilePtr, "Last %d Clock Speed Change Timers (nanoseconds):\n", NUM_EXTRA_POWER_STATS);
2467 pfnOSStatsPrintf(pvFilePtr, "Prepare DVFS\tDVFS Change\tPost DVFS\n");
2469 for (ui32Idx = ui32ClockSpeedIndexStart; ui32Idx !=ui32ClockSpeedIndexEnd; ui32Idx = (ui32Idx + 1) % NUM_EXTRA_POWER_STATS)
2471 pfnOSStatsPrintf(pvFilePtr, "%12llu\t%11llu\t%9llu\n",asClockSpeedChanges[ui32Idx].ui64PreClockSpeedChangeDuration,
2472 asClockSpeedChanges[ui32Idx].ui64BetweenPreEndingAndPostStartingDuration,
2473 asClockSpeedChanges[ui32Idx].ui64PostClockSpeedChangeDuration);
2477 } /* PowerStatsPrintElements */
2480 IMG_VOID GlobalStatsPrintElements(IMG_PVOID pvFilePtr,
2481 IMG_PVOID pvStatPtr,
2482 OS_STATS_PRINTF_FUNC* pfnOSGetStatsPrintf)
2484 PVR_UNREFERENCED_PARAMETER(pvStatPtr);
2486 if (pfnOSGetStatsPrintf != IMG_NULL)
2488 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageKMalloc %10d\n", gsGlobalStats.ui32MemoryUsageKMalloc);
2489 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageKMallocMax %10d\n", gsGlobalStats.ui32MemoryUsageKMallocMax);
2490 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMalloc %10d\n", gsGlobalStats.ui32MemoryUsageVMalloc);
2491 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMallocMax %10d\n", gsGlobalStats.ui32MemoryUsageVMallocMax);
2492 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryUMA %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMA);
2493 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryUMAMax %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryUMAMax);
2494 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMapPTUMA %10d\n", gsGlobalStats.ui32MemoryUsageVMapPTUMA);
2495 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageVMapPTUMAMax %10d\n", gsGlobalStats.ui32MemoryUsageVMapPTUMAMax);
2496 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryLMA %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMA);
2497 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocPTMemoryLMAMax %10d\n", gsGlobalStats.ui32MemoryUsageAllocPTMemoryLMAMax);
2498 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageIORemapPTLMA %10d\n", gsGlobalStats.ui32MemoryUsageIORemapPTLMA);
2499 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageIORemapPTLMAMax %10d\n", gsGlobalStats.ui32MemoryUsageIORemapPTLMAMax);
2500 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemLMA %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemLMA);
2501 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemLMAMax %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemLMAMax);
2502 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMA %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMA);
2503 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMAMax %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAMax);
2504 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMAPool %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPool);
2505 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageAllocGPUMemUMAPoolMax %10d\n", gsGlobalStats.ui32MemoryUsageAllocGPUMemUMAPoolMax);
2506 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageMappedGPUMemUMA/LMA %10d\n", gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMA);
2507 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageMappedGPUMemUMA/LMAMax %10d\n", gsGlobalStats.ui32MemoryUsageMappedGPUMemUMA_LMAMax);
2509 //zxl: count total data
2510 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageTotalAlloc %10d\n",gsGlobalStats.ui32MemoryUsageTotalAlloc);
2511 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageTotalAllocMax %10d\n",gsGlobalStats.ui32MemoryUsageTotalAllocMax);
2512 pfnOSGetStatsPrintf(pvFilePtr, "MemoryUsageTotalMap %10d\n",gsGlobalStats.ui32MemoryUsageTotalMap);
2513 pfnOSGetStatsPrintf(pvFilePtr, "ui32MemoryUsageTotalMapMax %10d\n",gsGlobalStats.ui32MemoryUsageTotalMapMax);