dbstats.c revision 281075
1/*******************************************************************************
2 *
3 * Module Name: dbstats - Generation and display of ACPI table statistics
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acdebug.h>
47#include <contrib/dev/acpica/include/acnamesp.h>
48
49#ifdef ACPI_DEBUGGER
50
51#define _COMPONENT          ACPI_CA_DEBUGGER
52        ACPI_MODULE_NAME    ("dbstats")
53
54/* Local prototypes */
55
56static void
57AcpiDbCountNamespaceObjects (
58    void);
59
60static void
61AcpiDbEnumerateObject (
62    ACPI_OPERAND_OBJECT     *ObjDesc);
63
64static ACPI_STATUS
65AcpiDbClassifyOneObject (
66    ACPI_HANDLE             ObjHandle,
67    UINT32                  NestingLevel,
68    void                    *Context,
69    void                    **ReturnValue);
70
71#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
72static void
73AcpiDbListInfo (
74    ACPI_MEMORY_LIST        *List);
75#endif
76
77
78/*
79 * Statistics subcommands
80 */
81static ACPI_DB_ARGUMENT_INFO    AcpiDbStatTypes [] =
82{
83    {"ALLOCATIONS"},
84    {"OBJECTS"},
85    {"MEMORY"},
86    {"MISC"},
87    {"TABLES"},
88    {"SIZES"},
89    {"STACK"},
90    {NULL}           /* Must be null terminated */
91};
92
93#define CMD_STAT_ALLOCATIONS     0
94#define CMD_STAT_OBJECTS         1
95#define CMD_STAT_MEMORY          2
96#define CMD_STAT_MISC            3
97#define CMD_STAT_TABLES          4
98#define CMD_STAT_SIZES           5
99#define CMD_STAT_STACK           6
100
101
102#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
103/*******************************************************************************
104 *
105 * FUNCTION:    AcpiDbListInfo
106 *
107 * PARAMETERS:  List            - Memory list/cache to be displayed
108 *
109 * RETURN:      None
110 *
111 * DESCRIPTION: Display information about the input memory list or cache.
112 *
113 ******************************************************************************/
114
115static void
116AcpiDbListInfo (
117    ACPI_MEMORY_LIST        *List)
118{
119#ifdef ACPI_DBG_TRACK_ALLOCATIONS
120    UINT32                  Outstanding;
121#endif
122
123    AcpiOsPrintf ("\n%s\n", List->ListName);
124
125    /* MaxDepth > 0 indicates a cache object */
126
127    if (List->MaxDepth > 0)
128    {
129        AcpiOsPrintf (
130            "    Cache: [Depth    MaxD Avail  Size]                %8.2X %8.2X %8.2X %8.2X\n",
131            List->CurrentDepth,
132            List->MaxDepth,
133            List->MaxDepth - List->CurrentDepth,
134            (List->CurrentDepth * List->ObjectSize));
135    }
136
137#ifdef ACPI_DBG_TRACK_ALLOCATIONS
138    if (List->MaxDepth > 0)
139    {
140        AcpiOsPrintf (
141            "    Cache: [Requests Hits Misses ObjSize]             %8.2X %8.2X %8.2X %8.2X\n",
142            List->Requests,
143            List->Hits,
144            List->Requests - List->Hits,
145            List->ObjectSize);
146    }
147
148    Outstanding = AcpiDbGetCacheInfo (List);
149
150    if (List->ObjectSize)
151    {
152        AcpiOsPrintf (
153            "    Mem:   [Alloc    Free Max    CurSize Outstanding] %8.2X %8.2X %8.2X %8.2X %8.2X\n",
154            List->TotalAllocated,
155            List->TotalFreed,
156            List->MaxOccupied,
157            Outstanding * List->ObjectSize,
158            Outstanding);
159    }
160    else
161    {
162        AcpiOsPrintf (
163            "    Mem:   [Alloc Free Max CurSize Outstanding Total] %8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
164            List->TotalAllocated,
165            List->TotalFreed,
166            List->MaxOccupied,
167            List->CurrentTotalSize,
168            Outstanding,
169            List->TotalSize);
170    }
171#endif
172}
173#endif
174
175
176/*******************************************************************************
177 *
178 * FUNCTION:    AcpiDbEnumerateObject
179 *
180 * PARAMETERS:  ObjDesc             - Object to be counted
181 *
182 * RETURN:      None
183 *
184 * DESCRIPTION: Add this object to the global counts, by object type.
185 *              Limited recursion handles subobjects and packages, and this
186 *              is probably acceptable within the AML debugger only.
187 *
188 ******************************************************************************/
189
190static void
191AcpiDbEnumerateObject (
192    ACPI_OPERAND_OBJECT     *ObjDesc)
193{
194    UINT32                  i;
195
196
197    if (!ObjDesc)
198    {
199        return;
200    }
201
202    /* Enumerate this object first */
203
204    AcpiGbl_NumObjects++;
205
206    if (ObjDesc->Common.Type > ACPI_TYPE_NS_NODE_MAX)
207    {
208        AcpiGbl_ObjTypeCountMisc++;
209    }
210    else
211    {
212        AcpiGbl_ObjTypeCount [ObjDesc->Common.Type]++;
213    }
214
215    /* Count the sub-objects */
216
217    switch (ObjDesc->Common.Type)
218    {
219    case ACPI_TYPE_PACKAGE:
220
221        for (i = 0; i < ObjDesc->Package.Count; i++)
222        {
223            AcpiDbEnumerateObject (ObjDesc->Package.Elements[i]);
224        }
225        break;
226
227    case ACPI_TYPE_DEVICE:
228
229        AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[0]);
230        AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[1]);
231        AcpiDbEnumerateObject (ObjDesc->Device.Handler);
232        break;
233
234    case ACPI_TYPE_BUFFER_FIELD:
235
236        if (AcpiNsGetSecondaryObject (ObjDesc))
237        {
238            AcpiGbl_ObjTypeCount [ACPI_TYPE_BUFFER_FIELD]++;
239        }
240        break;
241
242    case ACPI_TYPE_REGION:
243
244        AcpiGbl_ObjTypeCount [ACPI_TYPE_LOCAL_REGION_FIELD ]++;
245        AcpiDbEnumerateObject (ObjDesc->Region.Handler);
246        break;
247
248    case ACPI_TYPE_POWER:
249
250        AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[0]);
251        AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[1]);
252        break;
253
254    case ACPI_TYPE_PROCESSOR:
255
256        AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[0]);
257        AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[1]);
258        AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
259        break;
260
261    case ACPI_TYPE_THERMAL:
262
263        AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[0]);
264        AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[1]);
265        AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
266        break;
267
268    default:
269
270        break;
271    }
272}
273
274
275/*******************************************************************************
276 *
277 * FUNCTION:    AcpiDbClassifyOneObject
278 *
279 * PARAMETERS:  Callback for WalkNamespace
280 *
281 * RETURN:      Status
282 *
283 * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
284 *              the parent namespace node.
285 *
286 ******************************************************************************/
287
288static ACPI_STATUS
289AcpiDbClassifyOneObject (
290    ACPI_HANDLE             ObjHandle,
291    UINT32                  NestingLevel,
292    void                    *Context,
293    void                    **ReturnValue)
294{
295    ACPI_NAMESPACE_NODE     *Node;
296    ACPI_OPERAND_OBJECT     *ObjDesc;
297    UINT32                  Type;
298
299
300    AcpiGbl_NumNodes++;
301
302    Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
303    ObjDesc = AcpiNsGetAttachedObject (Node);
304
305    AcpiDbEnumerateObject (ObjDesc);
306
307    Type = Node->Type;
308    if (Type > ACPI_TYPE_NS_NODE_MAX)
309    {
310        AcpiGbl_NodeTypeCountMisc++;
311    }
312    else
313    {
314        AcpiGbl_NodeTypeCount [Type]++;
315    }
316
317    return (AE_OK);
318
319
320#ifdef ACPI_FUTURE_IMPLEMENTATION
321
322    /* TBD: These need to be counted during the initial parsing phase */
323
324    if (AcpiPsIsNamedOp (Op->Opcode))
325    {
326        NumNodes++;
327    }
328
329    if (IsMethod)
330    {
331        NumMethodElements++;
332    }
333
334    NumGrammarElements++;
335    Op = AcpiPsGetDepthNext (Root, Op);
336
337    SizeOfParseTree   = (NumGrammarElements - NumMethodElements) *
338                            (UINT32) sizeof (ACPI_PARSE_OBJECT);
339    SizeOfMethodTrees = NumMethodElements * (UINT32) sizeof (ACPI_PARSE_OBJECT);
340    SizeOfNodeEntries = NumNodes * (UINT32) sizeof (ACPI_NAMESPACE_NODE);
341    SizeOfAcpiObjects = NumNodes * (UINT32) sizeof (ACPI_OPERAND_OBJECT);
342#endif
343}
344
345
346/*******************************************************************************
347 *
348 * FUNCTION:    AcpiDbCountNamespaceObjects
349 *
350 * PARAMETERS:  None
351 *
352 * RETURN:      None
353 *
354 * DESCRIPTION: Count and classify the entire namespace, including all
355 *              namespace nodes and attached objects.
356 *
357 ******************************************************************************/
358
359static void
360AcpiDbCountNamespaceObjects (
361    void)
362{
363    UINT32                  i;
364
365
366    AcpiGbl_NumNodes = 0;
367    AcpiGbl_NumObjects = 0;
368
369    AcpiGbl_ObjTypeCountMisc = 0;
370    for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
371    {
372        AcpiGbl_ObjTypeCount [i] = 0;
373        AcpiGbl_NodeTypeCount [i] = 0;
374    }
375
376    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
377                ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
378}
379
380
381/*******************************************************************************
382 *
383 * FUNCTION:    AcpiDbDisplayStatistics
384 *
385 * PARAMETERS:  TypeArg         - Subcommand
386 *
387 * RETURN:      Status
388 *
389 * DESCRIPTION: Display various statistics
390 *
391 ******************************************************************************/
392
393ACPI_STATUS
394AcpiDbDisplayStatistics (
395    char                    *TypeArg)
396{
397    UINT32                  i;
398    UINT32                  Temp;
399
400
401    AcpiUtStrupr (TypeArg);
402    Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
403    if (Temp == ACPI_TYPE_NOT_FOUND)
404    {
405        AcpiOsPrintf ("Invalid or unsupported argument\n");
406        return (AE_OK);
407    }
408
409
410    switch (Temp)
411    {
412    case CMD_STAT_ALLOCATIONS:
413
414#ifdef ACPI_DBG_TRACK_ALLOCATIONS
415        AcpiUtDumpAllocationInfo ();
416#endif
417        break;
418
419    case CMD_STAT_TABLES:
420
421        AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
422        break;
423
424    case CMD_STAT_OBJECTS:
425
426        AcpiDbCountNamespaceObjects ();
427
428        AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
429
430        AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
431            "ACPI_TYPE", "NODES", "OBJECTS");
432
433        for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
434        {
435            AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
436                AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
437        }
438        AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
439            AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
440
441        AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
442            AcpiGbl_NumNodes, AcpiGbl_NumObjects);
443        break;
444
445    case CMD_STAT_MEMORY:
446
447#ifdef ACPI_DBG_TRACK_ALLOCATIONS
448        AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
449
450        AcpiDbListInfo (AcpiGbl_GlobalList);
451        AcpiDbListInfo (AcpiGbl_NsNodeList);
452#endif
453
454#ifdef ACPI_USE_LOCAL_CACHE
455        AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
456        AcpiDbListInfo (AcpiGbl_OperandCache);
457        AcpiDbListInfo (AcpiGbl_PsNodeCache);
458        AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
459        AcpiDbListInfo (AcpiGbl_StateCache);
460#endif
461
462        break;
463
464    case CMD_STAT_MISC:
465
466        AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
467        AcpiOsPrintf ("Calls to AcpiPsFind:..  ........% 7ld\n",
468            AcpiGbl_PsFindCount);
469        AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
470            AcpiGbl_NsLookupCount);
471
472        AcpiOsPrintf ("\n");
473
474        AcpiOsPrintf ("Mutex usage:\n\n");
475        for (i = 0; i < ACPI_NUM_MUTEX; i++)
476        {
477            AcpiOsPrintf ("%-28s:       % 7ld\n",
478                AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
479        }
480        break;
481
482    case CMD_STAT_SIZES:
483
484        AcpiOsPrintf ("\nInternal object sizes:\n\n");
485
486        AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
487        AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
488        AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
489        AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
490        AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
491        AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
492        AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
493        AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
494        AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
495        AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
496        AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
497        AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
498        AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
499        AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
500        AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
501        AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
502        AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
503        AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
504        AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
505        AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
506        AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
507        AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));
508
509        AcpiOsPrintf ("\n");
510
511        AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
512        AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
513        AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
514        AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
515        AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
516        AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));
517
518        AcpiOsPrintf ("\n");
519
520        AcpiOsPrintf ("Generic State    %3d\n", sizeof (ACPI_GENERIC_STATE));
521        AcpiOsPrintf ("Common State     %3d\n", sizeof (ACPI_COMMON_STATE));
522        AcpiOsPrintf ("Control State    %3d\n", sizeof (ACPI_CONTROL_STATE));
523        AcpiOsPrintf ("Update State     %3d\n", sizeof (ACPI_UPDATE_STATE));
524        AcpiOsPrintf ("Scope State      %3d\n", sizeof (ACPI_SCOPE_STATE));
525        AcpiOsPrintf ("Parse Scope      %3d\n", sizeof (ACPI_PSCOPE_STATE));
526        AcpiOsPrintf ("Package State    %3d\n", sizeof (ACPI_PKG_STATE));
527        AcpiOsPrintf ("Thread State     %3d\n", sizeof (ACPI_THREAD_STATE));
528        AcpiOsPrintf ("Result Values    %3d\n", sizeof (ACPI_RESULT_VALUES));
529        AcpiOsPrintf ("Notify Info      %3d\n", sizeof (ACPI_NOTIFY_INFO));
530        break;
531
532    case CMD_STAT_STACK:
533#if defined(ACPI_DEBUG_OUTPUT)
534
535        Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
536
537        AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
538        AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
539        AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
540        AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
541        AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
542#endif
543        break;
544
545    default:
546
547        break;
548    }
549
550    AcpiOsPrintf ("\n");
551    return (AE_OK);
552}
553
554#endif /* ACPI_DEBUGGER  */
555