Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: dbstats - Generation and display of ACPI table statistics
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acdebug.h"
0011 #include "acnamesp.h"
0012 
0013 #define _COMPONENT          ACPI_CA_DEBUGGER
0014 ACPI_MODULE_NAME("dbstats")
0015 
0016 /* Local prototypes */
0017 static void acpi_db_count_namespace_objects(void);
0018 
0019 static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
0020 
0021 static acpi_status
0022 acpi_db_classify_one_object(acpi_handle obj_handle,
0023                 u32 nesting_level,
0024                 void *context, void **return_value);
0025 
0026 #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
0027 static void acpi_db_list_info(struct acpi_memory_list *list);
0028 #endif
0029 
0030 /*
0031  * Statistics subcommands
0032  */
0033 static struct acpi_db_argument_info acpi_db_stat_types[] = {
0034     {"ALLOCATIONS"},
0035     {"OBJECTS"},
0036     {"MEMORY"},
0037     {"MISC"},
0038     {"TABLES"},
0039     {"SIZES"},
0040     {"STACK"},
0041     {NULL}          /* Must be null terminated */
0042 };
0043 
0044 #define CMD_STAT_ALLOCATIONS     0
0045 #define CMD_STAT_OBJECTS         1
0046 #define CMD_STAT_MEMORY          2
0047 #define CMD_STAT_MISC            3
0048 #define CMD_STAT_TABLES          4
0049 #define CMD_STAT_SIZES           5
0050 #define CMD_STAT_STACK           6
0051 
0052 #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
0053 /*******************************************************************************
0054  *
0055  * FUNCTION:    acpi_db_list_info
0056  *
0057  * PARAMETERS:  list            - Memory list/cache to be displayed
0058  *
0059  * RETURN:      None
0060  *
0061  * DESCRIPTION: Display information about the input memory list or cache.
0062  *
0063  ******************************************************************************/
0064 
0065 static void acpi_db_list_info(struct acpi_memory_list *list)
0066 {
0067 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0068     u32 outstanding;
0069 #endif
0070 
0071     acpi_os_printf("\n%s\n", list->list_name);
0072 
0073     /* max_depth > 0 indicates a cache object */
0074 
0075     if (list->max_depth > 0) {
0076         acpi_os_printf
0077             ("    Cache: [Depth    MaxD Avail  Size]                "
0078              "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth,
0079              list->max_depth, list->max_depth - list->current_depth,
0080              (list->current_depth * list->object_size));
0081     }
0082 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0083     if (list->max_depth > 0) {
0084         acpi_os_printf
0085             ("    Cache: [Requests Hits Misses ObjSize]             "
0086              "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits,
0087              list->requests - list->hits, list->object_size);
0088     }
0089 
0090     outstanding = acpi_db_get_cache_info(list);
0091 
0092     if (list->object_size) {
0093         acpi_os_printf
0094             ("    Mem:   [Alloc    Free Max    CurSize Outstanding] "
0095              "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated,
0096              list->total_freed, list->max_occupied,
0097              outstanding * list->object_size, outstanding);
0098     } else {
0099         acpi_os_printf
0100             ("    Mem:   [Alloc Free Max CurSize Outstanding Total] "
0101              "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
0102              list->total_allocated, list->total_freed,
0103              list->max_occupied, list->current_total_size, outstanding,
0104              list->total_size);
0105     }
0106 #endif
0107 }
0108 #endif
0109 
0110 /*******************************************************************************
0111  *
0112  * FUNCTION:    acpi_db_enumerate_object
0113  *
0114  * PARAMETERS:  obj_desc            - Object to be counted
0115  *
0116  * RETURN:      None
0117  *
0118  * DESCRIPTION: Add this object to the global counts, by object type.
0119  *              Limited recursion handles subobjects and packages, and this
0120  *              is probably acceptable within the AML debugger only.
0121  *
0122  ******************************************************************************/
0123 
0124 static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc)
0125 {
0126     u32 i;
0127 
0128     if (!obj_desc) {
0129         return;
0130     }
0131 
0132     /* Enumerate this object first */
0133 
0134     acpi_gbl_num_objects++;
0135 
0136     if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
0137         acpi_gbl_obj_type_count_misc++;
0138     } else {
0139         acpi_gbl_obj_type_count[obj_desc->common.type]++;
0140     }
0141 
0142     /* Count the sub-objects */
0143 
0144     switch (obj_desc->common.type) {
0145     case ACPI_TYPE_PACKAGE:
0146 
0147         for (i = 0; i < obj_desc->package.count; i++) {
0148             acpi_db_enumerate_object(obj_desc->package.elements[i]);
0149         }
0150         break;
0151 
0152     case ACPI_TYPE_DEVICE:
0153 
0154         acpi_db_enumerate_object(obj_desc->device.notify_list[0]);
0155         acpi_db_enumerate_object(obj_desc->device.notify_list[1]);
0156         acpi_db_enumerate_object(obj_desc->device.handler);
0157         break;
0158 
0159     case ACPI_TYPE_BUFFER_FIELD:
0160 
0161         if (acpi_ns_get_secondary_object(obj_desc)) {
0162             acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++;
0163         }
0164         break;
0165 
0166     case ACPI_TYPE_REGION:
0167 
0168         acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++;
0169         acpi_db_enumerate_object(obj_desc->region.handler);
0170         break;
0171 
0172     case ACPI_TYPE_POWER:
0173 
0174         acpi_db_enumerate_object(obj_desc->power_resource.
0175                      notify_list[0]);
0176         acpi_db_enumerate_object(obj_desc->power_resource.
0177                      notify_list[1]);
0178         break;
0179 
0180     case ACPI_TYPE_PROCESSOR:
0181 
0182         acpi_db_enumerate_object(obj_desc->processor.notify_list[0]);
0183         acpi_db_enumerate_object(obj_desc->processor.notify_list[1]);
0184         acpi_db_enumerate_object(obj_desc->processor.handler);
0185         break;
0186 
0187     case ACPI_TYPE_THERMAL:
0188 
0189         acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]);
0190         acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]);
0191         acpi_db_enumerate_object(obj_desc->thermal_zone.handler);
0192         break;
0193 
0194     default:
0195 
0196         break;
0197     }
0198 }
0199 
0200 /*******************************************************************************
0201  *
0202  * FUNCTION:    acpi_db_classify_one_object
0203  *
0204  * PARAMETERS:  Callback for walk_namespace
0205  *
0206  * RETURN:      Status
0207  *
0208  * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
0209  *              the parent namespace node.
0210  *
0211  ******************************************************************************/
0212 
0213 static acpi_status
0214 acpi_db_classify_one_object(acpi_handle obj_handle,
0215                 u32 nesting_level,
0216                 void *context, void **return_value)
0217 {
0218     struct acpi_namespace_node *node;
0219     union acpi_operand_object *obj_desc;
0220     u32 type;
0221 
0222     acpi_gbl_num_nodes++;
0223 
0224     node = (struct acpi_namespace_node *)obj_handle;
0225     obj_desc = acpi_ns_get_attached_object(node);
0226 
0227     acpi_db_enumerate_object(obj_desc);
0228 
0229     type = node->type;
0230     if (type > ACPI_TYPE_NS_NODE_MAX) {
0231         acpi_gbl_node_type_count_misc++;
0232     } else {
0233         acpi_gbl_node_type_count[type]++;
0234     }
0235 
0236     return (AE_OK);
0237 
0238 #ifdef ACPI_FUTURE_IMPLEMENTATION
0239 
0240     /* TBD: These need to be counted during the initial parsing phase */
0241 
0242     if (acpi_ps_is_named_op(op->opcode)) {
0243         num_nodes++;
0244     }
0245 
0246     if (is_method) {
0247         num_method_elements++;
0248     }
0249 
0250     num_grammar_elements++;
0251     op = acpi_ps_get_depth_next(root, op);
0252 
0253     size_of_parse_tree = (num_grammar_elements - num_method_elements) *
0254         (u32)sizeof(union acpi_parse_object);
0255     size_of_method_trees =
0256         num_method_elements * (u32)sizeof(union acpi_parse_object);
0257     size_of_node_entries =
0258         num_nodes * (u32)sizeof(struct acpi_namespace_node);
0259     size_of_acpi_objects =
0260         num_nodes * (u32)sizeof(union acpi_operand_object);
0261 #endif
0262 }
0263 
0264 /*******************************************************************************
0265  *
0266  * FUNCTION:    acpi_db_count_namespace_objects
0267  *
0268  * PARAMETERS:  None
0269  *
0270  * RETURN:      None
0271  *
0272  * DESCRIPTION: Count and classify the entire namespace, including all
0273  *              namespace nodes and attached objects.
0274  *
0275  ******************************************************************************/
0276 
0277 static void acpi_db_count_namespace_objects(void)
0278 {
0279     u32 i;
0280 
0281     acpi_gbl_num_nodes = 0;
0282     acpi_gbl_num_objects = 0;
0283 
0284     acpi_gbl_obj_type_count_misc = 0;
0285     for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) {
0286         acpi_gbl_obj_type_count[i] = 0;
0287         acpi_gbl_node_type_count[i] = 0;
0288     }
0289 
0290     (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
0291                      ACPI_UINT32_MAX, FALSE,
0292                      acpi_db_classify_one_object, NULL, NULL,
0293                      NULL);
0294 }
0295 
0296 /*******************************************************************************
0297  *
0298  * FUNCTION:    acpi_db_display_statistics
0299  *
0300  * PARAMETERS:  type_arg        - Subcommand
0301  *
0302  * RETURN:      Status
0303  *
0304  * DESCRIPTION: Display various statistics
0305  *
0306  ******************************************************************************/
0307 
0308 acpi_status acpi_db_display_statistics(char *type_arg)
0309 {
0310     u32 i;
0311     u32 temp;
0312 
0313     acpi_ut_strupr(type_arg);
0314     temp = acpi_db_match_argument(type_arg, acpi_db_stat_types);
0315     if (temp == ACPI_TYPE_NOT_FOUND) {
0316         acpi_os_printf("Invalid or unsupported argument\n");
0317         return (AE_OK);
0318     }
0319 
0320     switch (temp) {
0321     case CMD_STAT_ALLOCATIONS:
0322 
0323 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0324         acpi_ut_dump_allocation_info();
0325 #endif
0326         break;
0327 
0328     case CMD_STAT_TABLES:
0329 
0330         acpi_os_printf("ACPI Table Information (not implemented):\n\n");
0331         break;
0332 
0333     case CMD_STAT_OBJECTS:
0334 
0335         acpi_db_count_namespace_objects();
0336 
0337         acpi_os_printf
0338             ("\nObjects defined in the current namespace:\n\n");
0339 
0340         acpi_os_printf("%16.16s %10.10s %10.10s\n",
0341                    "ACPI_TYPE", "NODES", "OBJECTS");
0342 
0343         for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
0344             acpi_os_printf("%16.16s %10u %10u\n",
0345                        acpi_ut_get_type_name(i),
0346                        acpi_gbl_node_type_count[i],
0347                        acpi_gbl_obj_type_count[i]);
0348         }
0349 
0350         acpi_os_printf("%16.16s %10u %10u\n", "Misc/Unknown",
0351                    acpi_gbl_node_type_count_misc,
0352                    acpi_gbl_obj_type_count_misc);
0353 
0354         acpi_os_printf("%16.16s %10u %10u\n", "TOTALS:",
0355                    acpi_gbl_num_nodes, acpi_gbl_num_objects);
0356         break;
0357 
0358     case CMD_STAT_MEMORY:
0359 
0360 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0361         acpi_os_printf
0362             ("\n----Object Statistics (all in hex)---------\n");
0363 
0364         acpi_db_list_info(acpi_gbl_global_list);
0365         acpi_db_list_info(acpi_gbl_ns_node_list);
0366 #endif
0367 
0368 #ifdef ACPI_USE_LOCAL_CACHE
0369         acpi_os_printf
0370             ("\n----Cache Statistics (all in hex)---------\n");
0371         acpi_db_list_info(acpi_gbl_operand_cache);
0372         acpi_db_list_info(acpi_gbl_ps_node_cache);
0373         acpi_db_list_info(acpi_gbl_ps_node_ext_cache);
0374         acpi_db_list_info(acpi_gbl_state_cache);
0375 #endif
0376 
0377         break;
0378 
0379     case CMD_STAT_MISC:
0380 
0381         acpi_os_printf("\nMiscellaneous Statistics:\n\n");
0382         acpi_os_printf("%-28s:     %7u\n", "Calls to AcpiPsFind",
0383                    acpi_gbl_ps_find_count);
0384         acpi_os_printf("%-28s:     %7u\n", "Calls to AcpiNsLookup",
0385                    acpi_gbl_ns_lookup_count);
0386 
0387         acpi_os_printf("\nMutex usage:\n\n");
0388         for (i = 0; i < ACPI_NUM_MUTEX; i++) {
0389             acpi_os_printf("%-28s:     %7u\n",
0390                        acpi_ut_get_mutex_name(i),
0391                        acpi_gbl_mutex_info[i].use_count);
0392         }
0393         break;
0394 
0395     case CMD_STAT_SIZES:
0396 
0397         acpi_os_printf("\nInternal object sizes:\n\n");
0398 
0399         acpi_os_printf("Common         %3d\n",
0400                    (u32)sizeof(struct acpi_object_common));
0401         acpi_os_printf("Number         %3d\n",
0402                    (u32)sizeof(struct acpi_object_integer));
0403         acpi_os_printf("String         %3d\n",
0404                    (u32)sizeof(struct acpi_object_string));
0405         acpi_os_printf("Buffer         %3d\n",
0406                    (u32)sizeof(struct acpi_object_buffer));
0407         acpi_os_printf("Package        %3d\n",
0408                    (u32)sizeof(struct acpi_object_package));
0409         acpi_os_printf("BufferField    %3d\n",
0410                    (u32)sizeof(struct acpi_object_buffer_field));
0411         acpi_os_printf("Device         %3d\n",
0412                    (u32)sizeof(struct acpi_object_device));
0413         acpi_os_printf("Event          %3d\n",
0414                    (u32)sizeof(struct acpi_object_event));
0415         acpi_os_printf("Method         %3d\n",
0416                    (u32)sizeof(struct acpi_object_method));
0417         acpi_os_printf("Mutex          %3d\n",
0418                    (u32)sizeof(struct acpi_object_mutex));
0419         acpi_os_printf("Region         %3d\n",
0420                    (u32)sizeof(struct acpi_object_region));
0421         acpi_os_printf("PowerResource  %3d\n",
0422                    (u32)sizeof(struct acpi_object_power_resource));
0423         acpi_os_printf("Processor      %3d\n",
0424                    (u32)sizeof(struct acpi_object_processor));
0425         acpi_os_printf("ThermalZone    %3d\n",
0426                    (u32)sizeof(struct acpi_object_thermal_zone));
0427         acpi_os_printf("RegionField    %3d\n",
0428                    (u32)sizeof(struct acpi_object_region_field));
0429         acpi_os_printf("BankField      %3d\n",
0430                    (u32)sizeof(struct acpi_object_bank_field));
0431         acpi_os_printf("IndexField     %3d\n",
0432                    (u32)sizeof(struct acpi_object_index_field));
0433         acpi_os_printf("Reference      %3d\n",
0434                    (u32)sizeof(struct acpi_object_reference));
0435         acpi_os_printf("Notify         %3d\n",
0436                    (u32)sizeof(struct acpi_object_notify_handler));
0437         acpi_os_printf("AddressSpace   %3d\n",
0438                    (u32)sizeof(struct acpi_object_addr_handler));
0439         acpi_os_printf("Extra          %3d\n",
0440                    (u32)sizeof(struct acpi_object_extra));
0441         acpi_os_printf("Data           %3d\n",
0442                    (u32)sizeof(struct acpi_object_data));
0443 
0444         acpi_os_printf("\n");
0445 
0446         acpi_os_printf("ParseObject    %3d\n",
0447                    (u32)sizeof(struct acpi_parse_obj_common));
0448         acpi_os_printf("ParseObjectNamed %3d\n",
0449                    (u32)sizeof(struct acpi_parse_obj_named));
0450         acpi_os_printf("ParseObjectAsl %3d\n",
0451                    (u32)sizeof(struct acpi_parse_obj_asl));
0452         acpi_os_printf("OperandObject  %3d\n",
0453                    (u32)sizeof(union acpi_operand_object));
0454         acpi_os_printf("NamespaceNode  %3d\n",
0455                    (u32)sizeof(struct acpi_namespace_node));
0456         acpi_os_printf("AcpiObject     %3d\n",
0457                    (u32)sizeof(union acpi_object));
0458 
0459         acpi_os_printf("\n");
0460 
0461         acpi_os_printf("Generic State  %3d\n",
0462                    (u32)sizeof(union acpi_generic_state));
0463         acpi_os_printf("Common State   %3d\n",
0464                    (u32)sizeof(struct acpi_common_state));
0465         acpi_os_printf("Control State  %3d\n",
0466                    (u32)sizeof(struct acpi_control_state));
0467         acpi_os_printf("Update State   %3d\n",
0468                    (u32)sizeof(struct acpi_update_state));
0469         acpi_os_printf("Scope State    %3d\n",
0470                    (u32)sizeof(struct acpi_scope_state));
0471         acpi_os_printf("Parse Scope    %3d\n",
0472                    (u32)sizeof(struct acpi_pscope_state));
0473         acpi_os_printf("Package State  %3d\n",
0474                    (u32)sizeof(struct acpi_pkg_state));
0475         acpi_os_printf("Thread State   %3d\n",
0476                    (u32)sizeof(struct acpi_thread_state));
0477         acpi_os_printf("Result Values  %3d\n",
0478                    (u32)sizeof(struct acpi_result_values));
0479         acpi_os_printf("Notify Info    %3d\n",
0480                    (u32)sizeof(struct acpi_notify_info));
0481         break;
0482 
0483     case CMD_STAT_STACK:
0484 #if defined(ACPI_DEBUG_OUTPUT)
0485 
0486         temp =
0487             (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer,
0488                        acpi_gbl_lowest_stack_pointer);
0489 
0490         acpi_os_printf("\nSubsystem Stack Usage:\n\n");
0491         acpi_os_printf("Entry Stack Pointer        %p\n",
0492                    acpi_gbl_entry_stack_pointer);
0493         acpi_os_printf("Lowest Stack Pointer       %p\n",
0494                    acpi_gbl_lowest_stack_pointer);
0495         acpi_os_printf("Stack Use                  %X (%u)\n", temp,
0496                    temp);
0497         acpi_os_printf("Deepest Procedure Nesting  %u\n",
0498                    acpi_gbl_deepest_nesting);
0499 #endif
0500         break;
0501 
0502     default:
0503 
0504         break;
0505     }
0506 
0507     acpi_os_printf("\n");
0508     return (AE_OK);
0509 }