Home | History | Annotate | Line # | Download | only in debugger
dbstats.c revision 1.1.1.2
      1 /*******************************************************************************
      2  *
      3  * Module Name: dbstats - Generation and display of ACPI table statistics
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, 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 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.SystemNotify);
    231         AcpiDbEnumerateObject (ObjDesc->Device.DeviceNotify);
    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.SystemNotify);
    252         AcpiDbEnumerateObject (ObjDesc->PowerResource.DeviceNotify);
    253         break;
    254 
    255     case ACPI_TYPE_PROCESSOR:
    256 
    257         AcpiDbEnumerateObject (ObjDesc->Processor.SystemNotify);
    258         AcpiDbEnumerateObject (ObjDesc->Processor.DeviceNotify);
    259         AcpiDbEnumerateObject (ObjDesc->Processor.Handler);
    260         break;
    261 
    262     case ACPI_TYPE_THERMAL:
    263 
    264         AcpiDbEnumerateObject (ObjDesc->ThermalZone.SystemNotify);
    265         AcpiDbEnumerateObject (ObjDesc->ThermalZone.DeviceNotify);
    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 
    288 static ACPI_STATUS
    289 AcpiDbClassifyOneObject (
    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 
    359 static void
    360 AcpiDbCountNamespaceObjects (
    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 
    393 ACPI_STATUS
    394 AcpiDbDisplayStatistics (
    395     char                    *TypeArg)
    396 {
    397     UINT32                  i;
    398     UINT32                  Temp;
    399 
    400 
    401     if (!TypeArg)
    402     {
    403         AcpiOsPrintf ("The following subcommands are available:\n    ALLOCATIONS, OBJECTS, MEMORY, MISC, SIZES, TABLES\n");
    404         return (AE_OK);
    405     }
    406 
    407     AcpiUtStrupr (TypeArg);
    408     Temp = AcpiDbMatchArgument (TypeArg, AcpiDbStatTypes);
    409     if (Temp == (UINT32) -1)
    410     {
    411         AcpiOsPrintf ("Invalid or unsupported argument\n");
    412         return (AE_OK);
    413     }
    414 
    415 
    416     switch (Temp)
    417     {
    418     case CMD_STAT_ALLOCATIONS:
    419 
    420 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    421         AcpiUtDumpAllocationInfo ();
    422 #endif
    423         break;
    424 
    425     case CMD_STAT_TABLES:
    426 
    427         AcpiOsPrintf ("ACPI Table Information (not implemented):\n\n");
    428         break;
    429 
    430     case CMD_STAT_OBJECTS:
    431 
    432         AcpiDbCountNamespaceObjects ();
    433 
    434         AcpiOsPrintf ("\nObjects defined in the current namespace:\n\n");
    435 
    436         AcpiOsPrintf ("%16.16s %10.10s %10.10s\n",
    437             "ACPI_TYPE", "NODES", "OBJECTS");
    438 
    439         for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++)
    440         {
    441             AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", AcpiUtGetTypeName (i),
    442                 AcpiGbl_NodeTypeCount [i], AcpiGbl_ObjTypeCount [i]);
    443         }
    444         AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
    445             AcpiGbl_NodeTypeCountMisc, AcpiGbl_ObjTypeCountMisc);
    446 
    447         AcpiOsPrintf ("%16.16s % 10ld% 10ld\n", "TOTALS:",
    448             AcpiGbl_NumNodes, AcpiGbl_NumObjects);
    449         break;
    450 
    451     case CMD_STAT_MEMORY:
    452 
    453 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
    454         AcpiOsPrintf ("\n----Object Statistics (all in hex)---------\n");
    455 
    456         AcpiDbListInfo (AcpiGbl_GlobalList);
    457         AcpiDbListInfo (AcpiGbl_NsNodeList);
    458 #endif
    459 
    460 #ifdef ACPI_USE_LOCAL_CACHE
    461         AcpiOsPrintf ("\n----Cache Statistics (all in hex)---------\n");
    462         AcpiDbListInfo (AcpiGbl_OperandCache);
    463         AcpiDbListInfo (AcpiGbl_PsNodeCache);
    464         AcpiDbListInfo (AcpiGbl_PsNodeExtCache);
    465         AcpiDbListInfo (AcpiGbl_StateCache);
    466 #endif
    467 
    468         break;
    469 
    470     case CMD_STAT_MISC:
    471 
    472         AcpiOsPrintf ("\nMiscellaneous Statistics:\n\n");
    473         AcpiOsPrintf ("Calls to AcpiPsFind:..  ........% 7ld\n",
    474             AcpiGbl_PsFindCount);
    475         AcpiOsPrintf ("Calls to AcpiNsLookup:..........% 7ld\n",
    476             AcpiGbl_NsLookupCount);
    477 
    478         AcpiOsPrintf ("\n");
    479 
    480         AcpiOsPrintf ("Mutex usage:\n\n");
    481         for (i = 0; i < ACPI_NUM_MUTEX; i++)
    482         {
    483             AcpiOsPrintf ("%-28s:       % 7ld\n",
    484                 AcpiUtGetMutexName (i), AcpiGbl_MutexInfo[i].UseCount);
    485         }
    486         break;
    487 
    488 
    489     case CMD_STAT_SIZES:
    490 
    491         AcpiOsPrintf ("\nInternal object sizes:\n\n");
    492 
    493         AcpiOsPrintf ("Common           %3d\n", sizeof (ACPI_OBJECT_COMMON));
    494         AcpiOsPrintf ("Number           %3d\n", sizeof (ACPI_OBJECT_INTEGER));
    495         AcpiOsPrintf ("String           %3d\n", sizeof (ACPI_OBJECT_STRING));
    496         AcpiOsPrintf ("Buffer           %3d\n", sizeof (ACPI_OBJECT_BUFFER));
    497         AcpiOsPrintf ("Package          %3d\n", sizeof (ACPI_OBJECT_PACKAGE));
    498         AcpiOsPrintf ("BufferField      %3d\n", sizeof (ACPI_OBJECT_BUFFER_FIELD));
    499         AcpiOsPrintf ("Device           %3d\n", sizeof (ACPI_OBJECT_DEVICE));
    500         AcpiOsPrintf ("Event            %3d\n", sizeof (ACPI_OBJECT_EVENT));
    501         AcpiOsPrintf ("Method           %3d\n", sizeof (ACPI_OBJECT_METHOD));
    502         AcpiOsPrintf ("Mutex            %3d\n", sizeof (ACPI_OBJECT_MUTEX));
    503         AcpiOsPrintf ("Region           %3d\n", sizeof (ACPI_OBJECT_REGION));
    504         AcpiOsPrintf ("PowerResource    %3d\n", sizeof (ACPI_OBJECT_POWER_RESOURCE));
    505         AcpiOsPrintf ("Processor        %3d\n", sizeof (ACPI_OBJECT_PROCESSOR));
    506         AcpiOsPrintf ("ThermalZone      %3d\n", sizeof (ACPI_OBJECT_THERMAL_ZONE));
    507         AcpiOsPrintf ("RegionField      %3d\n", sizeof (ACPI_OBJECT_REGION_FIELD));
    508         AcpiOsPrintf ("BankField        %3d\n", sizeof (ACPI_OBJECT_BANK_FIELD));
    509         AcpiOsPrintf ("IndexField       %3d\n", sizeof (ACPI_OBJECT_INDEX_FIELD));
    510         AcpiOsPrintf ("Reference        %3d\n", sizeof (ACPI_OBJECT_REFERENCE));
    511         AcpiOsPrintf ("Notify           %3d\n", sizeof (ACPI_OBJECT_NOTIFY_HANDLER));
    512         AcpiOsPrintf ("AddressSpace     %3d\n", sizeof (ACPI_OBJECT_ADDR_HANDLER));
    513         AcpiOsPrintf ("Extra            %3d\n", sizeof (ACPI_OBJECT_EXTRA));
    514         AcpiOsPrintf ("Data             %3d\n", sizeof (ACPI_OBJECT_DATA));
    515 
    516         AcpiOsPrintf ("\n");
    517 
    518         AcpiOsPrintf ("ParseObject      %3d\n", sizeof (ACPI_PARSE_OBJ_COMMON));
    519         AcpiOsPrintf ("ParseObjectNamed %3d\n", sizeof (ACPI_PARSE_OBJ_NAMED));
    520         AcpiOsPrintf ("ParseObjectAsl   %3d\n", sizeof (ACPI_PARSE_OBJ_ASL));
    521         AcpiOsPrintf ("OperandObject    %3d\n", sizeof (ACPI_OPERAND_OBJECT));
    522         AcpiOsPrintf ("NamespaceNode    %3d\n", sizeof (ACPI_NAMESPACE_NODE));
    523         AcpiOsPrintf ("AcpiObject       %3d\n", sizeof (ACPI_OBJECT));
    524 
    525         break;
    526 
    527 
    528     case CMD_STAT_STACK:
    529 #if defined(ACPI_DEBUG_OUTPUT)
    530 
    531         Temp = (UINT32) ACPI_PTR_DIFF (AcpiGbl_EntryStackPointer, AcpiGbl_LowestStackPointer);
    532 
    533         AcpiOsPrintf ("\nSubsystem Stack Usage:\n\n");
    534         AcpiOsPrintf ("Entry Stack Pointer          %p\n", AcpiGbl_EntryStackPointer);
    535         AcpiOsPrintf ("Lowest Stack Pointer         %p\n", AcpiGbl_LowestStackPointer);
    536         AcpiOsPrintf ("Stack Use                    %X (%u)\n", Temp, Temp);
    537         AcpiOsPrintf ("Deepest Procedure Nesting    %u\n", AcpiGbl_DeepestNesting);
    538 #endif
    539         break;
    540 
    541     default:
    542         break;
    543     }
    544 
    545     AcpiOsPrintf ("\n");
    546     return (AE_OK);
    547 }
    548 
    549 #endif /* ACPI_DEBUGGER  */
    550