dbstats.c revision 306536
1/*******************************************************************************
2 *
3 * Module Name: dbstats - Generation and display of ACPI table statistics
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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
50#define _COMPONENT          ACPI_CA_DEBUGGER
51        ACPI_MODULE_NAME    ("dbstats")
52
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]                "
131            "%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]             "
143            "%8.2X %8.2X %8.2X %8.2X\n",
144            List->Requests,
145            List->Hits,
146            List->Requests - List->Hits,
147            List->ObjectSize);
148    }
149
150    Outstanding = AcpiDbGetCacheInfo (List);
151
152    if (List->ObjectSize)
153    {
154        AcpiOsPrintf (
155            "    Mem:   [Alloc    Free Max    CurSize Outstanding] "
156            "%8.2X %8.2X %8.2X %8.2X %8.2X\n",
157            List->TotalAllocated,
158            List->TotalFreed,
159            List->MaxOccupied,
160            Outstanding * List->ObjectSize,
161            Outstanding);
162    }
163    else
164    {
165        AcpiOsPrintf (
166            "    Mem:   [Alloc Free Max CurSize Outstanding Total] "
167            "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
168            List->TotalAllocated,
169            List->TotalFreed,
170            List->MaxOccupied,
171            List->CurrentTotalSize,
172            Outstanding,
173            List->TotalSize);
174    }
175#endif
176}
177#endif
178
179
180/*******************************************************************************
181 *
182 * FUNCTION:    AcpiDbEnumerateObject
183 *
184 * PARAMETERS:  ObjDesc             - Object to be counted
185 *
186 * RETURN:      None
187 *
188 * DESCRIPTION: Add this object to the global counts, by object type.
189 *              Limited recursion handles subobjects and packages, and this
190 *              is probably acceptable within the AML debugger only.
191 *
192 ******************************************************************************/
193
194static void
195AcpiDbEnumerateObject (
196    ACPI_OPERAND_OBJECT     *ObjDesc)
197{
198    UINT32                  i;
199
200
201    if (!ObjDesc)
202    {
203        return;
204    }
205
206    /* Enumerate this object first */
207
208    AcpiGbl_NumObjects++;
209
210    if (ObjDesc->Common.Type > ACPI_TYPE_NS_NODE_MAX)
211    {
212        AcpiGbl_ObjTypeCountMisc++;
213    }
214    else
215    {
216        AcpiGbl_ObjTypeCount [ObjDesc->Common.Type]++;
217    }
218
219    /* Count the sub-objects */
220
221    switch (ObjDesc->Common.Type)
222    {
223    case ACPI_TYPE_PACKAGE:
224
225        for (i = 0; i < ObjDesc->Package.Count; i++)
226        {
227            AcpiDbEnumerateObject (ObjDesc->Package.Elements[i]);
228        }
229        break;
230
231    case ACPI_TYPE_DEVICE:
232
233        AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[0]);
234        AcpiDbEnumerateObject (ObjDesc->Device.NotifyList[1]);
235        AcpiDbEnumerateObject (ObjDesc->Device.Handler);
236        break;
237
238    case ACPI_TYPE_BUFFER_FIELD:
239
240        if (AcpiNsGetSecondaryObject (ObjDesc))
241        {
242            AcpiGbl_ObjTypeCount [ACPI_TYPE_BUFFER_FIELD]++;
243        }
244        break;
245
246    case ACPI_TYPE_REGION:
247
248        AcpiGbl_ObjTypeCount [ACPI_TYPE_LOCAL_REGION_FIELD ]++;
249        AcpiDbEnumerateObject (ObjDesc->Region.Handler);
250        break;
251
252    case ACPI_TYPE_POWER:
253
254        AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[0]);
255        AcpiDbEnumerateObject (ObjDesc->PowerResource.NotifyList[1]);
256        break;
257
258    case ACPI_TYPE_PROCESSOR:
259
260        AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[0]);
261        AcpiDbEnumerateObject (ObjDesc->Processor.NotifyList[1]);
262        AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
263        break;
264
265    case ACPI_TYPE_THERMAL:
266
267        AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[0]);
268        AcpiDbEnumerateObject (ObjDesc->ThermalZone.NotifyList[1]);
269        AcpiDbEnumerateObject (ObjDesc->ThermalZone.Handler);
270        break;
271
272    default:
273
274        break;
275    }
276}
277
278
279/*******************************************************************************
280 *
281 * FUNCTION:    AcpiDbClassifyOneObject
282 *
283 * PARAMETERS:  Callback for WalkNamespace
284 *
285 * RETURN:      Status
286 *
287 * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
288 *              the parent namespace node.
289 *
290 ******************************************************************************/
291
292static ACPI_STATUS
293AcpiDbClassifyOneObject (
294    ACPI_HANDLE             ObjHandle,
295    UINT32                  NestingLevel,
296    void                    *Context,
297    void                    **ReturnValue)
298{
299    ACPI_NAMESPACE_NODE     *Node;
300    ACPI_OPERAND_OBJECT     *ObjDesc;
301    UINT32                  Type;
302
303
304    AcpiGbl_NumNodes++;
305
306    Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
307    ObjDesc = AcpiNsGetAttachedObject (Node);
308
309    AcpiDbEnumerateObject (ObjDesc);
310
311    Type = Node->Type;
312    if (Type > ACPI_TYPE_NS_NODE_MAX)
313    {
314        AcpiGbl_NodeTypeCountMisc++;
315    }
316    else
317    {
318        AcpiGbl_NodeTypeCount [Type]++;
319    }
320
321    return (AE_OK);
322
323
324#ifdef ACPI_FUTURE_IMPLEMENTATION
325
326    /* TBD: These need to be counted during the initial parsing phase */
327
328    if (AcpiPsIsNamedOp (Op->Opcode))
329    {
330        NumNodes++;
331    }
332
333    if (IsMethod)
334    {
335        NumMethodElements++;
336    }
337
338    NumGrammarElements++;
339    Op = AcpiPsGetDepthNext (Root, Op);
340
341    SizeOfParseTree   = (NumGrammarElements - NumMethodElements) *
342        (UINT32) sizeof (ACPI_PARSE_OBJECT);
343    SizeOfMethodTrees = NumMethodElements * (UINT32) sizeof (ACPI_PARSE_OBJECT);
344    SizeOfNodeEntries = NumNodes * (UINT32) sizeof (ACPI_NAMESPACE_NODE);
345    SizeOfAcpiObjects = NumNodes * (UINT32) sizeof (ACPI_OPERAND_OBJECT);
346#endif
347}
348
349
350/*******************************************************************************
351 *
352 * FUNCTION:    AcpiDbCountNamespaceObjects
353 *
354 * PARAMETERS:  None
355 *
356 * RETURN:      None
357 *
358 * DESCRIPTION: Count and classify the entire namespace, including all
359 *              namespace nodes and attached objects.
360 *
361 ******************************************************************************/
362
363static void
364AcpiDbCountNamespaceObjects (
365    void)
366{
367    UINT32                  i;
368
369
370    AcpiGbl_NumNodes = 0;
371    AcpiGbl_NumObjects = 0;
372
373    AcpiGbl_ObjTypeCountMisc = 0;
374    for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
375    {
376        AcpiGbl_ObjTypeCount [i] = 0;
377        AcpiGbl_NodeTypeCount [i] = 0;
378    }
379
380    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
381        ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
382}
383
384
385/*******************************************************************************
386 *
387 * FUNCTION:    AcpiDbDisplayStatistics
388 *
389 * PARAMETERS:  TypeArg         - Subcommand
390 *
391 * RETURN:      Status
392 *
393 * DESCRIPTION: Display various statistics
394 *
395 ******************************************************************************/
396
397ACPI_STATUS
398AcpiDbDisplayStatistics (
399    char                    *TypeArg)
400{
401    UINT32                  i;
402    UINT32                  Temp;
403
404
405    AcpiUtStrupr (TypeArg);
406    Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
407    if (Temp == ACPI_TYPE_NOT_FOUND)
408    {
409        AcpiOsPrintf ("Invalid or unsupported argument\n");
410        return (AE_OK);
411    }
412
413
414    switch (Temp)
415    {
416    case CMD_STAT_ALLOCATIONS:
417
418#ifdef ACPI_DBG_TRACK_ALLOCATIONS
419        AcpiUtDumpAllocationInfo ();
420#endif
421        break;
422
423    case CMD_STAT_TABLES:
424
425        AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
426        break;
427
428    case CMD_STAT_OBJECTS:
429
430        AcpiDbCountNamespaceObjects ();
431
432        AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
433
434        AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
435            "ACPI_TYPE", "NODES", "OBJECTS");
436
437        for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
438        {
439            AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
440                AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
441        }
442
443        AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
444            AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
445
446        AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
447            AcpiGbl_NumNodes, AcpiGbl_NumObjects);
448        break;
449
450    case CMD_STAT_MEMORY:
451
452#ifdef ACPI_DBG_TRACK_ALLOCATIONS
453        AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
454
455        AcpiDbListInfo (AcpiGbl_GlobalList);
456        AcpiDbListInfo (AcpiGbl_NsNodeList);
457#endif
458
459#ifdef ACPI_USE_LOCAL_CACHE
460        AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
461        AcpiDbListInfo (AcpiGbl_OperandCache);
462        AcpiDbListInfo (AcpiGbl_PsNodeCache);
463        AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
464        AcpiDbListInfo (AcpiGbl_StateCache);
465#endif
466
467        break;
468
469    case CMD_STAT_MISC:
470
471        AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
472        AcpiOsPrintf ("Calls to AcpiPsFind:..  ........% 7ld\n",
473            AcpiGbl_PsFindCount);
474        AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
475            AcpiGbl_NsLookupCount);
476
477        AcpiOsPrintf ("\n");
478
479        AcpiOsPrintf ("Mutex usage:\n\n");
480        for (i = 0; i < ACPI_NUM_MUTEX; i++)
481        {
482            AcpiOsPrintf ("%-28s:       % 7ld\n",
483                AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
484        }
485        break;
486
487    case CMD_STAT_SIZES:
488
489        AcpiOsPrintf ("\nInternal object sizes:\n\n");
490
491        AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
492        AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
493        AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
494        AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
495        AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
496        AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
497        AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
498        AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
499        AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
500        AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
501        AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
502        AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
503        AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
504        AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
505        AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
506        AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
507        AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
508        AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
509        AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
510        AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
511        AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
512        AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));
513
514        AcpiOsPrintf ("\n");
515
516        AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
517        AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
518        AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
519        AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
520        AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
521        AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));
522
523        AcpiOsPrintf ("\n");
524
525        AcpiOsPrintf ("Generic State    %3d\n", sizeof (ACPI_GENERIC_STATE));
526        AcpiOsPrintf ("Common State     %3d\n", sizeof (ACPI_COMMON_STATE));
527        AcpiOsPrintf ("Control State    %3d\n", sizeof (ACPI_CONTROL_STATE));
528        AcpiOsPrintf ("Update State     %3d\n", sizeof (ACPI_UPDATE_STATE));
529        AcpiOsPrintf ("Scope State      %3d\n", sizeof (ACPI_SCOPE_STATE));
530        AcpiOsPrintf ("Parse Scope      %3d\n", sizeof (ACPI_PSCOPE_STATE));
531        AcpiOsPrintf ("Package State    %3d\n", sizeof (ACPI_PKG_STATE));
532        AcpiOsPrintf ("Thread State     %3d\n", sizeof (ACPI_THREAD_STATE));
533        AcpiOsPrintf ("Result Values    %3d\n", sizeof (ACPI_RESULT_VALUES));
534        AcpiOsPrintf ("Notify Info      %3d\n", sizeof (ACPI_NOTIFY_INFO));
535        break;
536
537    case CMD_STAT_STACK:
538#if defined(ACPI_DEBUG_OUTPUT)
539
540        Temp = (UINT32) ACPI_PTR_DIFF (
541            AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
542
543        AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
544        AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
545        AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
546        AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
547        AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
548#endif
549        break;
550
551    default:
552
553        break;
554    }
555
556    AcpiOsPrintf ("\n");
557    return (AE_OK);
558}
559