linux/drivers/acpi/acpica/dbstats.c
<<
>>
Prefs
   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
  14ACPI_MODULE_NAME("dbstats")
  15
  16/* Local prototypes */
  17static void acpi_db_count_namespace_objects(void);
  18
  19static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
  20
  21static acpi_status
  22acpi_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
  27static void acpi_db_list_info(struct acpi_memory_list *list);
  28#endif
  29
  30/*
  31 * Statistics subcommands
  32 */
  33static 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
  65static 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
 124static 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
 213static acpi_status
 214acpi_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
 277static 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
 308acpi_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}
 510