Home | History | Annotate | Line # | Download | only in debugger
dbstats.c revision 1.1.1.3
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbstats - Generation and display of ACPI table statistics
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, 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 "acpi.h"
     46 #include "accommon.h"
     47 #include "acdebug.h"
     48 #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 
     57 static void
     58 AcpiDbCountNamespaceObjects (
     59     void);
     60 
     61 static void
     62 AcpiDbEnumerateObject (
     63     ACPI_OPERAND_OBJECT     *ObjDesc);
     64 
     65 static ACPI_STATUS
     66 AcpiDbClassifyOneObject (
     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
     73 static void
     74 AcpiDbListInfo (
     75     ACPI_MEMORY_LIST        *List);
     76 #endif
     77 
     78 
     79 /*
     80  * Statistics subcommands
     81  */
     82 static 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 
    116 static void
    117 AcpiDbListInfo (
    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 
    191 static void
    192 AcpiDbEnumerateObject (
    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 
    271         break;
    272     }
    273 }
    274 
    275 
    276 /*******************************************************************************
    277  *
    278  * FUNCTION:    AcpiDbClassifyOneObject
    279  *
    280  * PARAMETERS:  Callback for WalkNamespace
    281  *
    282  * RETURN:      Status
    283  *
    284  * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
    285  *              the parent namespace node.
    286  *
    287  ******************************************************************************/
    288 
    289 static ACPI_STATUS
    290 AcpiDbClassifyOneObject (
    291     ACPI_HANDLE             ObjHandle,
    292     UINT32                  NestingLevel,
    293     void                    *Context,
    294     void                    **ReturnValue)
    295 {
    296     ACPI_NAMESPACE_NODE     *Node;
    297     ACPI_OPERAND_OBJECT     *ObjDesc;
    298     UINT32                  Type;
    299 
    300 
    301     AcpiGbl_NumNodes++;
    302 
    303     Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
    304     ObjDesc = AcpiNsGetAttachedObject (Node);
    305 
    306     AcpiDbEnumerateObject (ObjDesc);
    307 
    308     Type = Node->Type;
    309     if (Type > ACPI_TYPE_NS_NODE_MAX)
    310     {
    311         AcpiGbl_NodeTypeCountMisc++;
    312     }
    313     else
    314     {
    315         AcpiGbl_NodeTypeCount [Type]++;
    316     }
    317 
    318     return (AE_OK);
    319 
    320 
    321 #ifdef ACPI_FUTURE_IMPLEMENTATION
    322 
    323     /* TBD: These need to be counted during the initial parsing phase */
    324 
    325     if (AcpiPsIsNamedOp (Op->Opcode))
    326     {
    327         NumNodes++;
    328     }
    329 
    330     if (IsMethod)
    331     {
    332         NumMethodElements++;
    333     }
    334 
    335     NumGrammarElements++;
    336     Op = AcpiPsGetDepthNext (Root, Op);
    337 
    338     SizeOfParseTree   = (NumGrammarElements - NumMethodElements) *
    339                             (UINT32) sizeof (ACPI_PARSE_OBJECT);
    340     SizeOfMethodTrees = NumMethodElements * (UINT32) sizeof (ACPI_PARSE_OBJECT);
    341     SizeOfNodeEntries = NumNodes * (UINT32) sizeof (ACPI_NAMESPACE_NODE);
    342     SizeOfAcpiObjects = NumNodes * (UINT32) sizeof (ACPI_OPERAND_OBJECT);
    343 #endif
    344 }
    345 
    346 
    347 /*******************************************************************************
    348  *
    349  * FUNCTION:    AcpiDbCountNamespaceObjects
    350  *
    351  * PARAMETERS:  None
    352  *
    353  * RETURN:      None
    354  *
    355  * DESCRIPTION: Count and classify the entire namespace, including all
    356  *              namespace nodes and attached objects.
    357  *
    358  ******************************************************************************/
    359 
    360 static void
    361 AcpiDbCountNamespaceObjects (
    362     void)
    363 {
    364     UINT32                  i;
    365 
    366 
    367     AcpiGbl_NumNodes = 0;
    368     AcpiGbl_NumObjects = 0;
    369 
    370     AcpiGbl_ObjTypeCountMisc = 0;
    371     for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
    372     {
    373         AcpiGbl_ObjTypeCount [i] = 0;
    374         AcpiGbl_NodeTypeCount [i] = 0;
    375     }
    376 
    377     (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
    378                 ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
    379 }
    380 
    381 
    382 /*******************************************************************************
    383  *
    384  * FUNCTION:    AcpiDbDisplayStatistics
    385  *
    386  * PARAMETERS:  TypeArg         - Subcommand
    387  *
    388  * RETURN:      Status
    389  *
    390  * DESCRIPTION: Display various statistics
    391  *
    392  ******************************************************************************/
    393 
    394 ACPI_STATUS
    395 AcpiDbDisplayStatistics (
    396     char                    *TypeArg)
    397 {
    398     UINT32                  i;
    399     UINT32                  Temp;
    400 
    401 
    402     AcpiUtStrupr (TypeArg);
    403     Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
    404     if (Temp == (UINT32) -1)
    405     {
    406         AcpiOsPrintf ("Invalid or unsupported argument\n");
    407         return (AE_OK);
    408     }
    409 
    410 
    411     switch (Temp)
    412     {
    413     case CMD_STAT_ALLOCATIONS:
    414 
    415 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    416         AcpiUtDumpAllocationInfo ();
    417 #endif
    418         break;
    419 
    420     case CMD_STAT_TABLES:
    421 
    422         AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
    423         break;
    424 
    425     case CMD_STAT_OBJECTS:
    426 
    427         AcpiDbCountNamespaceObjects ();
    428 
    429         AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
    430 
    431         AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
    432             "ACPI_TYPE", "NODES", "OBJECTS");
    433 
    434         for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
    435         {
    436             AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
    437                 AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
    438         }
    439         AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
    440             AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
    441 
    442         AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
    443             AcpiGbl_NumNodes, AcpiGbl_NumObjects);
    444         break;
    445 
    446     case CMD_STAT_MEMORY:
    447 
    448 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    449         AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
    450 
    451         AcpiDbListInfo (AcpiGbl_GlobalList);
    452         AcpiDbListInfo (AcpiGbl_NsNodeList);
    453 #endif
    454 
    455 #ifdef ACPI_USE_LOCAL_CACHE
    456         AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
    457         AcpiDbListInfo (AcpiGbl_OperandCache);
    458         AcpiDbListInfo (AcpiGbl_PsNodeCache);
    459         AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
    460         AcpiDbListInfo (AcpiGbl_StateCache);
    461 #endif
    462 
    463         break;
    464 
    465     case CMD_STAT_MISC:
    466 
    467         AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
    468         AcpiOsPrintf ("Calls to AcpiPsFind:..  ........% 7ld\n",
    469             AcpiGbl_PsFindCount);
    470         AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
    471             AcpiGbl_NsLookupCount);
    472 
    473         AcpiOsPrintf ("\n");
    474 
    475         AcpiOsPrintf ("Mutex usage:\n\n");
    476         for (i = 0; i < ACPI_NUM_MUTEX; i++)
    477         {
    478             AcpiOsPrintf ("%-28s:       % 7ld\n",
    479                 AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
    480         }
    481         break;
    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     case CMD_STAT_STACK:
    534 #if defined(ACPI_DEBUG_OUTPUT)
    535 
    536         Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
    537 
    538         AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
    539         AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
    540         AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
    541         AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
    542         AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
    543 #endif
    544         break;
    545 
    546     default:
    547 
    548         break;
    549     }
    550 
    551     AcpiOsPrintf ("\n");
    552     return (AE_OK);
    553 }
    554 
    555 #endif /* ACPI_DEBUGGER  */
    556