root/drivers/acpi/acpica/dbstats.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_db_list_info
  2. acpi_db_enumerate_object
  3. acpi_db_classify_one_object
  4. acpi_db_count_namespace_objects
  5. acpi_db_display_statistics

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /*******************************************************************************
   3  *
   4  * Module Name: dbstats - Generation and display of ACPI table statistics
   5  *
   6  ******************************************************************************/
   7 
   8 #include <acpi/acpi.h>
   9 #include "accommon.h"
  10 #include "acdebug.h"
  11 #include "acnamesp.h"
  12 
  13 #define _COMPONENT          ACPI_CA_DEBUGGER
  14 ACPI_MODULE_NAME("dbstats")
  15 
  16 /* Local prototypes */
  17 static void acpi_db_count_namespace_objects(void);
  18 
  19 static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
  20 
  21 static acpi_status
  22 acpi_db_classify_one_object(acpi_handle obj_handle,
  23                             u32 nesting_level,
  24                             void *context, void **return_value);
  25 
  26 #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
  27 static void acpi_db_list_info(struct acpi_memory_list *list);
  28 #endif
  29 
  30 /*
  31  * Statistics subcommands
  32  */
  33 static struct acpi_db_argument_info acpi_db_stat_types[] = {
  34         {"ALLOCATIONS"},
  35         {"OBJECTS"},
  36         {"MEMORY"},
  37         {"MISC"},
  38         {"TABLES"},
  39         {"SIZES"},
  40         {"STACK"},
  41         {NULL}                  /* Must be null terminated */
  42 };
  43 
  44 #define CMD_STAT_ALLOCATIONS     0
  45 #define CMD_STAT_OBJECTS         1
  46 #define CMD_STAT_MEMORY          2
  47 #define CMD_STAT_MISC            3
  48 #define CMD_STAT_TABLES          4
  49 #define CMD_STAT_SIZES           5
  50 #define CMD_STAT_STACK           6
  51 
  52 #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
  53 /*******************************************************************************
  54  *
  55  * FUNCTION:    acpi_db_list_info
  56  *
  57  * PARAMETERS:  list            - Memory list/cache to be displayed
  58  *
  59  * RETURN:      None
  60  *
  61  * DESCRIPTION: Display information about the input memory list or cache.
  62  *
  63  ******************************************************************************/
  64 
  65 static void acpi_db_list_info(struct acpi_memory_list *list)
  66 {
  67 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  68         u32 outstanding;
  69 #endif
  70 
  71         acpi_os_printf("\n%s\n", list->list_name);
  72 
  73         /* max_depth > 0 indicates a cache object */
  74 
  75         if (list->max_depth > 0) {
  76                 acpi_os_printf
  77                     ("    Cache: [Depth    MaxD Avail  Size]                "
  78                      "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth,
  79                      list->max_depth, list->max_depth - list->current_depth,
  80                      (list->current_depth * list->object_size));
  81         }
  82 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  83         if (list->max_depth > 0) {
  84                 acpi_os_printf
  85                     ("    Cache: [Requests Hits Misses ObjSize]             "
  86                      "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits,
  87                      list->requests - list->hits, list->object_size);
  88         }
  89 
  90         outstanding = acpi_db_get_cache_info(list);
  91 
  92         if (list->object_size) {
  93                 acpi_os_printf
  94                     ("    Mem:   [Alloc    Free Max    CurSize Outstanding] "
  95                      "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated,
  96                      list->total_freed, list->max_occupied,
  97                      outstanding * list->object_size, outstanding);
  98         } else {
  99                 acpi_os_printf
 100                     ("    Mem:   [Alloc Free Max CurSize Outstanding Total] "
 101                      "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
 102                      list->total_allocated, list->total_freed,
 103                      list->max_occupied, list->current_total_size, outstanding,
 104                      list->total_size);
 105         }
 106 #endif
 107 }
 108 #endif
 109 
 110 /*******************************************************************************
 111  *
 112  * FUNCTION:    acpi_db_enumerate_object
 113  *
 114  * PARAMETERS:  obj_desc            - Object to be counted
 115  *
 116  * RETURN:      None
 117  *
 118  * DESCRIPTION: Add this object to the global counts, by object type.
 119  *              Limited recursion handles subobjects and packages, and this
 120  *              is probably acceptable within the AML debugger only.
 121  *
 122  ******************************************************************************/
 123 
 124 static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc)
 125 {
 126         u32 i;
 127 
 128         if (!obj_desc) {
 129                 return;
 130         }
 131 
 132         /* Enumerate this object first */
 133 
 134         acpi_gbl_num_objects++;
 135 
 136         if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
 137                 acpi_gbl_obj_type_count_misc++;
 138         } else {
 139                 acpi_gbl_obj_type_count[obj_desc->common.type]++;
 140         }
 141 
 142         /* Count the sub-objects */
 143 
 144         switch (obj_desc->common.type) {
 145         case ACPI_TYPE_PACKAGE:
 146 
 147                 for (i = 0; i < obj_desc->package.count; i++) {
 148                         acpi_db_enumerate_object(obj_desc->package.elements[i]);
 149                 }
 150                 break;
 151 
 152         case ACPI_TYPE_DEVICE:
 153 
 154                 acpi_db_enumerate_object(obj_desc->device.notify_list[0]);
 155                 acpi_db_enumerate_object(obj_desc->device.notify_list[1]);
 156                 acpi_db_enumerate_object(obj_desc->device.handler);
 157                 break;
 158 
 159         case ACPI_TYPE_BUFFER_FIELD:
 160 
 161                 if (acpi_ns_get_secondary_object(obj_desc)) {
 162                         acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++;
 163                 }
 164                 break;
 165 
 166         case ACPI_TYPE_REGION:
 167 
 168                 acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++;
 169                 acpi_db_enumerate_object(obj_desc->region.handler);
 170                 break;
 171 
 172         case ACPI_TYPE_POWER:
 173 
 174                 acpi_db_enumerate_object(obj_desc->power_resource.
 175                                          notify_list[0]);
 176                 acpi_db_enumerate_object(obj_desc->power_resource.
 177                                          notify_list[1]);
 178                 break;
 179 
 180         case ACPI_TYPE_PROCESSOR:
 181 
 182                 acpi_db_enumerate_object(obj_desc->processor.notify_list[0]);
 183                 acpi_db_enumerate_object(obj_desc->processor.notify_list[1]);
 184                 acpi_db_enumerate_object(obj_desc->processor.handler);
 185                 break;
 186 
 187         case ACPI_TYPE_THERMAL:
 188 
 189                 acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]);
 190                 acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]);
 191                 acpi_db_enumerate_object(obj_desc->thermal_zone.handler);
 192                 break;
 193 
 194         default:
 195 
 196                 break;
 197         }
 198 }
 199 
 200 /*******************************************************************************
 201  *
 202  * FUNCTION:    acpi_db_classify_one_object
 203  *
 204  * PARAMETERS:  Callback for walk_namespace
 205  *
 206  * RETURN:      Status
 207  *
 208  * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
 209  *              the parent namespace node.
 210  *
 211  ******************************************************************************/
 212 
 213 static acpi_status
 214 acpi_db_classify_one_object(acpi_handle obj_handle,
 215                             u32 nesting_level,
 216                             void *context, void **return_value)
 217 {
 218         struct acpi_namespace_node *node;
 219         union acpi_operand_object *obj_desc;
 220         u32 type;
 221 
 222         acpi_gbl_num_nodes++;
 223 
 224         node = (struct acpi_namespace_node *)obj_handle;
 225         obj_desc = acpi_ns_get_attached_object(node);
 226 
 227         acpi_db_enumerate_object(obj_desc);
 228 
 229         type = node->type;
 230         if (type > ACPI_TYPE_NS_NODE_MAX) {
 231                 acpi_gbl_node_type_count_misc++;
 232         } else {
 233                 acpi_gbl_node_type_count[type]++;
 234         }
 235 
 236         return (AE_OK);
 237 
 238 #ifdef ACPI_FUTURE_IMPLEMENTATION
 239 
 240         /* TBD: These need to be counted during the initial parsing phase */
 241 
 242         if (acpi_ps_is_named_op(op->opcode)) {
 243                 num_nodes++;
 244         }
 245 
 246         if (is_method) {
 247                 num_method_elements++;
 248         }
 249 
 250         num_grammar_elements++;
 251         op = acpi_ps_get_depth_next(root, op);
 252 
 253         size_of_parse_tree = (num_grammar_elements - num_method_elements) *
 254             (u32)sizeof(union acpi_parse_object);
 255         size_of_method_trees =
 256             num_method_elements * (u32)sizeof(union acpi_parse_object);
 257         size_of_node_entries =
 258             num_nodes * (u32)sizeof(struct acpi_namespace_node);
 259         size_of_acpi_objects =
 260             num_nodes * (u32)sizeof(union acpi_operand_object);
 261 #endif
 262 }
 263 
 264 /*******************************************************************************
 265  *
 266  * FUNCTION:    acpi_db_count_namespace_objects
 267  *
 268  * PARAMETERS:  None
 269  *
 270  * RETURN:      None
 271  *
 272  * DESCRIPTION: Count and classify the entire namespace, including all
 273  *              namespace nodes and attached objects.
 274  *
 275  ******************************************************************************/
 276 
 277 static void acpi_db_count_namespace_objects(void)
 278 {
 279         u32 i;
 280 
 281         acpi_gbl_num_nodes = 0;
 282         acpi_gbl_num_objects = 0;
 283 
 284         acpi_gbl_obj_type_count_misc = 0;
 285         for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) {
 286                 acpi_gbl_obj_type_count[i] = 0;
 287                 acpi_gbl_node_type_count[i] = 0;
 288         }
 289 
 290         (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 291                                      ACPI_UINT32_MAX, FALSE,
 292                                      acpi_db_classify_one_object, NULL, NULL,
 293                                      NULL);
 294 }
 295 
 296 /*******************************************************************************
 297  *
 298  * FUNCTION:    acpi_db_display_statistics
 299  *
 300  * PARAMETERS:  type_arg        - Subcommand
 301  *
 302  * RETURN:      Status
 303  *
 304  * DESCRIPTION: Display various statistics
 305  *
 306  ******************************************************************************/
 307 
 308 acpi_status acpi_db_display_statistics(char *type_arg)
 309 {
 310         u32 i;
 311         u32 temp;
 312 
 313         acpi_ut_strupr(type_arg);
 314         temp = acpi_db_match_argument(type_arg, acpi_db_stat_types);
 315         if (temp == ACPI_TYPE_NOT_FOUND) {
 316                 acpi_os_printf("Invalid or unsupported argument\n");
 317                 return (AE_OK);
 318         }
 319 
 320         switch (temp) {
 321         case CMD_STAT_ALLOCATIONS:
 322 
 323 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
 324                 acpi_ut_dump_allocation_info();
 325 #endif
 326                 break;
 327 
 328         case CMD_STAT_TABLES:
 329 
 330                 acpi_os_printf("ACPI Table Information (not implemented):\n\n");
 331                 break;
 332 
 333         case CMD_STAT_OBJECTS:
 334 
 335                 acpi_db_count_namespace_objects();
 336 
 337                 acpi_os_printf
 338                     ("\nObjects defined in the current namespace:\n\n");
 339 
 340                 acpi_os_printf("%16.16s %10.10s %10.10s\n",
 341                                "ACPI_TYPE", "NODES", "OBJECTS");
 342 
 343                 for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
 344                         acpi_os_printf("%16.16s %10u %10u\n",
 345                                        acpi_ut_get_type_name(i),
 346                                        acpi_gbl_node_type_count[i],
 347                                        acpi_gbl_obj_type_count[i]);
 348                 }
 349 
 350                 acpi_os_printf("%16.16s %10u %10u\n", "Misc/Unknown",
 351                                acpi_gbl_node_type_count_misc,
 352                                acpi_gbl_obj_type_count_misc);
 353 
 354                 acpi_os_printf("%16.16s %10u %10u\n", "TOTALS:",
 355                                acpi_gbl_num_nodes, acpi_gbl_num_objects);
 356                 break;
 357 
 358         case CMD_STAT_MEMORY:
 359 
 360 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
 361                 acpi_os_printf
 362                     ("\n----Object Statistics (all in hex)---------\n");
 363 
 364                 acpi_db_list_info(acpi_gbl_global_list);
 365                 acpi_db_list_info(acpi_gbl_ns_node_list);
 366 #endif
 367 
 368 #ifdef ACPI_USE_LOCAL_CACHE
 369                 acpi_os_printf
 370                     ("\n----Cache Statistics (all in hex)---------\n");
 371                 acpi_db_list_info(acpi_gbl_operand_cache);
 372                 acpi_db_list_info(acpi_gbl_ps_node_cache);
 373                 acpi_db_list_info(acpi_gbl_ps_node_ext_cache);
 374                 acpi_db_list_info(acpi_gbl_state_cache);
 375 #endif
 376 
 377                 break;
 378 
 379         case CMD_STAT_MISC:
 380 
 381                 acpi_os_printf("\nMiscellaneous Statistics:\n\n");
 382                 acpi_os_printf("%-28s:     %7u\n", "Calls to AcpiPsFind",
 383                                acpi_gbl_ps_find_count);
 384                 acpi_os_printf("%-28s:     %7u\n", "Calls to AcpiNsLookup",
 385                                acpi_gbl_ns_lookup_count);
 386 
 387                 acpi_os_printf("\nMutex usage:\n\n");
 388                 for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 389                         acpi_os_printf("%-28s:     %7u\n",
 390                                        acpi_ut_get_mutex_name(i),
 391                                        acpi_gbl_mutex_info[i].use_count);
 392                 }
 393                 break;
 394 
 395         case CMD_STAT_SIZES:
 396 
 397                 acpi_os_printf("\nInternal object sizes:\n\n");
 398 
 399                 acpi_os_printf("Common         %3d\n",
 400                                (u32)sizeof(struct acpi_object_common));
 401                 acpi_os_printf("Number         %3d\n",
 402                                (u32)sizeof(struct acpi_object_integer));
 403                 acpi_os_printf("String         %3d\n",
 404                                (u32)sizeof(struct acpi_object_string));
 405                 acpi_os_printf("Buffer         %3d\n",
 406                                (u32)sizeof(struct acpi_object_buffer));
 407                 acpi_os_printf("Package        %3d\n",
 408                                (u32)sizeof(struct acpi_object_package));
 409                 acpi_os_printf("BufferField    %3d\n",
 410                                (u32)sizeof(struct acpi_object_buffer_field));
 411                 acpi_os_printf("Device         %3d\n",
 412                                (u32)sizeof(struct acpi_object_device));
 413                 acpi_os_printf("Event          %3d\n",
 414                                (u32)sizeof(struct acpi_object_event));
 415                 acpi_os_printf("Method         %3d\n",
 416                                (u32)sizeof(struct acpi_object_method));
 417                 acpi_os_printf("Mutex          %3d\n",
 418                                (u32)sizeof(struct acpi_object_mutex));
 419                 acpi_os_printf("Region         %3d\n",
 420                                (u32)sizeof(struct acpi_object_region));
 421                 acpi_os_printf("PowerResource  %3d\n",
 422                                (u32)sizeof(struct acpi_object_power_resource));
 423                 acpi_os_printf("Processor      %3d\n",
 424                                (u32)sizeof(struct acpi_object_processor));
 425                 acpi_os_printf("ThermalZone    %3d\n",
 426                                (u32)sizeof(struct acpi_object_thermal_zone));
 427                 acpi_os_printf("RegionField    %3d\n",
 428                                (u32)sizeof(struct acpi_object_region_field));
 429                 acpi_os_printf("BankField      %3d\n",
 430                                (u32)sizeof(struct acpi_object_bank_field));
 431                 acpi_os_printf("IndexField     %3d\n",
 432                                (u32)sizeof(struct acpi_object_index_field));
 433                 acpi_os_printf("Reference      %3d\n",
 434                                (u32)sizeof(struct acpi_object_reference));
 435                 acpi_os_printf("Notify         %3d\n",
 436                                (u32)sizeof(struct acpi_object_notify_handler));
 437                 acpi_os_printf("AddressSpace   %3d\n",
 438                                (u32)sizeof(struct acpi_object_addr_handler));
 439                 acpi_os_printf("Extra          %3d\n",
 440                                (u32)sizeof(struct acpi_object_extra));
 441                 acpi_os_printf("Data           %3d\n",
 442                                (u32)sizeof(struct acpi_object_data));
 443 
 444                 acpi_os_printf("\n");
 445 
 446                 acpi_os_printf("ParseObject    %3d\n",
 447                                (u32)sizeof(struct acpi_parse_obj_common));
 448                 acpi_os_printf("ParseObjectNamed %3d\n",
 449                                (u32)sizeof(struct acpi_parse_obj_named));
 450                 acpi_os_printf("ParseObjectAsl %3d\n",
 451                                (u32)sizeof(struct acpi_parse_obj_asl));
 452                 acpi_os_printf("OperandObject  %3d\n",
 453                                (u32)sizeof(union acpi_operand_object));
 454                 acpi_os_printf("NamespaceNode  %3d\n",
 455                                (u32)sizeof(struct acpi_namespace_node));
 456                 acpi_os_printf("AcpiObject     %3d\n",
 457                                (u32)sizeof(union acpi_object));
 458 
 459                 acpi_os_printf("\n");
 460 
 461                 acpi_os_printf("Generic State  %3d\n",
 462                                (u32)sizeof(union acpi_generic_state));
 463                 acpi_os_printf("Common State   %3d\n",
 464                                (u32)sizeof(struct acpi_common_state));
 465                 acpi_os_printf("Control State  %3d\n",
 466                                (u32)sizeof(struct acpi_control_state));
 467                 acpi_os_printf("Update State   %3d\n",
 468                                (u32)sizeof(struct acpi_update_state));
 469                 acpi_os_printf("Scope State    %3d\n",
 470                                (u32)sizeof(struct acpi_scope_state));
 471                 acpi_os_printf("Parse Scope    %3d\n",
 472                                (u32)sizeof(struct acpi_pscope_state));
 473                 acpi_os_printf("Package State  %3d\n",
 474                                (u32)sizeof(struct acpi_pkg_state));
 475                 acpi_os_printf("Thread State   %3d\n",
 476                                (u32)sizeof(struct acpi_thread_state));
 477                 acpi_os_printf("Result Values  %3d\n",
 478                                (u32)sizeof(struct acpi_result_values));
 479                 acpi_os_printf("Notify Info    %3d\n",
 480                                (u32)sizeof(struct acpi_notify_info));
 481                 break;
 482 
 483         case CMD_STAT_STACK:
 484 #if defined(ACPI_DEBUG_OUTPUT)
 485 
 486                 temp =
 487                     (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer,
 488                                        acpi_gbl_lowest_stack_pointer);
 489 
 490                 acpi_os_printf("\nSubsystem Stack Usage:\n\n");
 491                 acpi_os_printf("Entry Stack Pointer        %p\n",
 492                                acpi_gbl_entry_stack_pointer);
 493                 acpi_os_printf("Lowest Stack Pointer       %p\n",
 494                                acpi_gbl_lowest_stack_pointer);
 495                 acpi_os_printf("Stack Use                  %X (%u)\n", temp,
 496                                temp);
 497                 acpi_os_printf("Deepest Procedure Nesting  %u\n",
 498                                acpi_gbl_deepest_nesting);
 499 #endif
 500                 break;
 501 
 502         default:
 503 
 504                 break;
 505         }
 506 
 507         acpi_os_printf("\n");
 508         return (AE_OK);
 509 }

/* [<][>][^][v][top][bottom][index][help] */