dbstats.c revision 241973
1/*******************************************************************************
2 *
3 * Module Name: dbstats - Generation and display of ACPI table statistics
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, 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
45#include <contrib/dev/acpica/include/acpi.h>
46#include <contrib/dev/acpica/include/accommon.h>
47#include <contrib/dev/acpica/include/acdebug.h>
48#include <contrib/dev/acpica/include/acnamesp.h>
49
50#ifdef ACPI_DEBUGGER
51
52#define _COMPONENT          ACPI_CA_DEBUGGER
53        ACPI_MODULE_NAME    ("dbstats")
54
55/* Local prototypes */
56
57static void
58AcpiDbCountNamespaceObjects (
59    void);
60
61static void
62AcpiDbEnumerateObject (
63    ACPI_OPERAND_OBJECT     *ObjDesc);
64
65static ACPI_STATUS
66AcpiDbClassifyOneObject (
67    ACPI_HANDLE             ObjHandle,
68    UINT32                  NestingLevel,
69    void                    *Context,
70    void                    **ReturnValue);
71
72#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
73static void
74AcpiDbListInfo (
75    ACPI_MEMORY_LIST        *List);
76#endif
77
78
79/*
80 * Statistics subcommands
81 */
82static ACPI_DB_ARGUMENT_INFO    AcpiDbStatTypes [] =
83{
84    {"ALLOCATIONS"},
85    {"OBJECTS"},
86    {"MEMORY"},
87    {"MISC"},
88    {"TABLES"},
89    {"SIZES"},
90    {"STACK"},
91    {NULL}           /* Must be null terminated */
92};
93
94#define CMD_STAT_ALLOCATIONS     0
95#define CMD_STAT_OBJECTS         1
96#define CMD_STAT_MEMORY          2
97#define CMD_STAT_MISC            3
98#define CMD_STAT_TABLES          4
99#define CMD_STAT_SIZES           5
100#define CMD_STAT_STACK           6
101
102
103#if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
104/*******************************************************************************
105 *
106 * FUNCTION:    AcpiDbListInfo
107 *
108 * PARAMETERS:  List            - Memory list/cache to be displayed
109 *
110 * RETURN:      None
111 *
112 * DESCRIPTION: Display information about the input memory list or cache.
113 *
114 ******************************************************************************/
115
116static void
117AcpiDbListInfo (
118    ACPI_MEMORY_LIST        *List)
119{
120#ifdef ACPI_DBG_TRACK_ALLOCATIONS
121    UINT32                  Outstanding;
122#endif
123
124    AcpiOsPrintf ("\n%s\n", List->ListName);
125
126    /* MaxDepth > 0 indicates a cache object */
127
128    if (List->MaxDepth > 0)
129    {
130        AcpiOsPrintf (
131            "    Cache: [Depth    MaxD Avail  Size]                %8.2X %8.2X %8.2X %8.2X\n",
132            List->CurrentDepth,
133            List->MaxDepth,
134            List->MaxDepth - List->CurrentDepth,
135            (List->CurrentDepth * List->ObjectSize));
136    }
137
138#ifdef ACPI_DBG_TRACK_ALLOCATIONS
139    if (List->MaxDepth > 0)
140    {
141        AcpiOsPrintf (
142            "    Cache: [Requests Hits Misses ObjSize]             %8.2X %8.2X %8.2X %8.2X\n",
143            List->Requests,
144            List->Hits,
145            List->Requests - List->Hits,
146            List->ObjectSize);
147    }
148
149    Outstanding = AcpiDbGetCacheInfo (List);
150
151    if (List->ObjectSize)
152    {
153        AcpiOsPrintf (
154            "    Mem:   [Alloc    Free Max    CurSize Outstanding] %8.2X %8.2X %8.2X %8.2X %8.2X\n",
155            List->TotalAllocated,
156            List->TotalFreed,
157            List->MaxOccupied,
158            Outstanding * List->ObjectSize,
159            Outstanding);
160    }
161    else
162    {
163        AcpiOsPrintf (
164            "    Mem:   [Alloc Free Max CurSize Outstanding Total] %8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
165            List->TotalAllocated,
166            List->TotalFreed,
167            List->MaxOccupied,
168            List->CurrentTotalSize,
169            Outstanding,
170            List->TotalSize);
171    }
172#endif
173}
174#endif
175
176
177/*******************************************************************************
178 *
179 * FUNCTION:    AcpiDbEnumerateObject
180 *
181 * PARAMETERS:  ObjDesc             - Object to be counted
182 *
183 * RETURN:      None
184 *
185 * DESCRIPTION: Add this object to the global counts, by object type.
186 *              Limited recursion handles subobjects and packages, and this
187 *              is probably acceptable within the AML debugger only.
188 *
189 ******************************************************************************/
190
191static void
192AcpiDbEnumerateObject (
193    ACPI_OPERAND_OBJECT     *ObjDesc)
194{
195    UINT32                  i;
196
197
198    if (!ObjDesc)
199    {
200        return;
201    }
202
203    /* Enumerate this object first */
204
205    AcpiGbl_NumObjects++;
206
207    if (ObjDesc->Common.Type > ACPI_TYPE_NS_NODE_MAX)
208    {
209        AcpiGbl_ObjTypeCountMisc++;
210    }
211    else
212    {
213        AcpiGbl_ObjTypeCount [ObjDesc->Common.Type]++;
214    }
215
216    /* Count the sub-objects */
217
218    switch (ObjDesc->Common.Type)
219    {
220    case ACPI_TYPE_PACKAGE:
221
222        for (i = 0; i < ObjDesc->Package.Count; i++)
223        {
224            AcpiDbEnumerateObject (ObjDesc->Package.Elements[i]);
225        }
226        break;
227
228    case ACPI_TYPE_DEVICE:
229
230        AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[0]);
231        AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[1]);
232        AcpiDbEnumerateObject (ObjDesc->Device.Handler);
233        break;
234
235    case ACPI_TYPE_BUFFER_FIELD:
236
237        if (AcpiNsGetSecondaryObject (ObjDesc))
238        {
239            AcpiGbl_ObjTypeCount [ACPI_TYPE_BUFFER_FIELD]++;
240        }
241        break;
242
243    case ACPI_TYPE_REGION:
244
245        AcpiGbl_ObjTypeCount [ACPI_TYPE_LOCAL_REGION_FIELD ]++;
246        AcpiDbEnumerateObject (ObjDesc->Region.Handler);
247        break;
248
249    case ACPI_TYPE_POWER:
250
251        AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[0]);
252        AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[1]);
253        break;
254
255    case ACPI_TYPE_PROCESSOR:
256
257        AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[0]);
258        AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[1]);
259        AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
260        break;
261
262    case ACPI_TYPE_THERMAL:
263
264        AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[0]);
265        AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[1]);
266        AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
267        break;
268
269    default:
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 == (UINT32) -1)
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
483    case CMD_STAT_SIZES:
484
485        AcpiOsPrintf ("\nInternal object sizes:\n\n");
486
487        AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
488        AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
489        AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
490        AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
491        AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
492        AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
493        AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
494        AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
495        AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
496        AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
497        AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
498        AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
499        AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
500        AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
501        AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
502        AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
503        AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
504        AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
505        AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
506        AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
507        AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
508        AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));
509
510        AcpiOsPrintf ("\n");
511
512        AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
513        AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
514        AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
515        AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
516        AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
517        AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));
518
519        AcpiOsPrintf ("\n");
520
521        AcpiOsPrintf ("Generic State    %3d\n", sizeof (ACPI_GENERIC_STATE));
522        AcpiOsPrintf ("Common State     %3d\n", sizeof (ACPI_COMMON_STATE));
523        AcpiOsPrintf ("Control State    %3d\n", sizeof (ACPI_CONTROL_STATE));
524        AcpiOsPrintf ("Update State     %3d\n", sizeof (ACPI_UPDATE_STATE));
525        AcpiOsPrintf ("Scope State      %3d\n", sizeof (ACPI_SCOPE_STATE));
526        AcpiOsPrintf ("Parse Scope      %3d\n", sizeof (ACPI_PSCOPE_STATE));
527        AcpiOsPrintf ("Package State    %3d\n", sizeof (ACPI_PKG_STATE));
528        AcpiOsPrintf ("Thread State     %3d\n", sizeof (ACPI_THREAD_STATE));
529        AcpiOsPrintf ("Result Values    %3d\n", sizeof (ACPI_RESULT_VALUES));
530        AcpiOsPrintf ("Notify Info      %3d\n", sizeof (ACPI_NOTIFY_INFO));
531        break;
532
533
534    case CMD_STAT_STACK:
535#if defined(ACPI_DEBUG_OUTPUT)
536
537        Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
538
539        AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
540        AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
541        AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
542        AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
543        AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
544#endif
545        break;
546
547    default:
548        break;
549    }
550
551    AcpiOsPrintf ("\n");
552    return (AE_OK);
553}
554
555#endif /* ACPI_DEBUGGER  */
556