Home | History | Annotate | Line # | Download | only in debugger
dbstats.c revision 1.1.1.9
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbstats - Generation and display of ACPI table statistics
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2019, 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 "acpi.h"
     45 #include "accommon.h"
     46 #include "acdebug.h"
     47 #include "acnamesp.h"
     48 
     49 
     50 #define _COMPONENT          ACPI_CA_DEBUGGER
     51         ACPI_MODULE_NAME    ("dbstats")
     52 
     53 
     54 /* Local prototypes */
     55 
     56 static void
     57 AcpiDbCountNamespaceObjects (
     58     void);
     59 
     60 static void
     61 AcpiDbEnumerateObject (
     62     ACPI_OPERAND_OBJECT     *ObjDesc);
     63 
     64 static ACPI_STATUS
     65 AcpiDbClassifyOneObject (
     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
     72 static void
     73 AcpiDbListInfo (
     74     ACPI_MEMORY_LIST        *List);
     75 #endif
     76 
     77 
     78 /*
     79  * Statistics subcommands
     80  */
     81 static 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 
    115 static void
    116 AcpiDbListInfo (
    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 
    194 static void
    195 AcpiDbEnumerateObject (
    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 
    292 static ACPI_STATUS
    293 AcpiDbClassifyOneObject (
    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 
    363 static void
    364 AcpiDbCountNamespaceObjects (
    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 
    397 ACPI_STATUS
    398 AcpiDbDisplayStatistics (
    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