diff options
Diffstat (limited to 'drivers/acpi/utilities/utalloc.c')
| -rw-r--r-- | drivers/acpi/utilities/utalloc.c | 634 |
1 files changed, 62 insertions, 572 deletions
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 03b0044974c2..7940fc1bd69e 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c | |||
| @@ -46,24 +46,6 @@ | |||
| 46 | #define _COMPONENT ACPI_UTILITIES | 46 | #define _COMPONENT ACPI_UTILITIES |
| 47 | ACPI_MODULE_NAME("utalloc") | 47 | ACPI_MODULE_NAME("utalloc") |
| 48 | 48 | ||
| 49 | /* Local prototypes */ | ||
| 50 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
| 51 | static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); | ||
| 52 | |||
| 53 | static acpi_status | ||
| 54 | acpi_ut_track_allocation(struct acpi_debug_mem_block *address, | ||
| 55 | acpi_size size, | ||
| 56 | u8 alloc_type, u32 component, char *module, u32 line); | ||
| 57 | |||
| 58 | static acpi_status | ||
| 59 | acpi_ut_remove_allocation(struct acpi_debug_mem_block *address, | ||
| 60 | u32 component, char *module, u32 line); | ||
| 61 | |||
| 62 | static acpi_status | ||
| 63 | acpi_ut_create_list(char *list_name, | ||
| 64 | u16 object_size, struct acpi_memory_list **return_cache); | ||
| 65 | #endif | ||
| 66 | |||
| 67 | /******************************************************************************* | 49 | /******************************************************************************* |
| 68 | * | 50 | * |
| 69 | * FUNCTION: acpi_ut_create_caches | 51 | * FUNCTION: acpi_ut_create_caches |
| @@ -75,33 +57,23 @@ acpi_ut_create_list(char *list_name, | |||
| 75 | * DESCRIPTION: Create all local caches | 57 | * DESCRIPTION: Create all local caches |
| 76 | * | 58 | * |
| 77 | ******************************************************************************/ | 59 | ******************************************************************************/ |
| 78 | |||
| 79 | acpi_status acpi_ut_create_caches(void) | 60 | acpi_status acpi_ut_create_caches(void) |
| 80 | { | 61 | { |
| 81 | acpi_status status; | 62 | acpi_status status; |
| 82 | 63 | ||
| 83 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | 64 | /* Object Caches, for frequently used objects */ |
| 84 | |||
| 85 | /* Memory allocation lists */ | ||
| 86 | |||
| 87 | status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); | ||
| 88 | if (ACPI_FAILURE(status)) { | ||
| 89 | return (status); | ||
| 90 | } | ||
| 91 | 65 | ||
| 92 | status = | 66 | status = |
| 93 | acpi_ut_create_list("Acpi-Namespace", | 67 | acpi_os_create_cache("Acpi-Namespace", |
| 94 | sizeof(struct acpi_namespace_node), | 68 | sizeof(struct acpi_namespace_node), |
| 95 | &acpi_gbl_ns_node_list); | 69 | ACPI_MAX_NAMESPACE_CACHE_DEPTH, |
| 70 | &acpi_gbl_namespace_cache); | ||
| 96 | if (ACPI_FAILURE(status)) { | 71 | if (ACPI_FAILURE(status)) { |
| 97 | return (status); | 72 | return (status); |
| 98 | } | 73 | } |
| 99 | #endif | ||
| 100 | |||
| 101 | /* Object Caches, for frequently used objects */ | ||
| 102 | 74 | ||
| 103 | status = | 75 | status = |
| 104 | acpi_os_create_cache("acpi_state", sizeof(union acpi_generic_state), | 76 | acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state), |
| 105 | ACPI_MAX_STATE_CACHE_DEPTH, | 77 | ACPI_MAX_STATE_CACHE_DEPTH, |
| 106 | &acpi_gbl_state_cache); | 78 | &acpi_gbl_state_cache); |
| 107 | if (ACPI_FAILURE(status)) { | 79 | if (ACPI_FAILURE(status)) { |
| @@ -109,7 +81,7 @@ acpi_status acpi_ut_create_caches(void) | |||
| 109 | } | 81 | } |
| 110 | 82 | ||
| 111 | status = | 83 | status = |
| 112 | acpi_os_create_cache("acpi_parse", | 84 | acpi_os_create_cache("Acpi-Parse", |
| 113 | sizeof(struct acpi_parse_obj_common), | 85 | sizeof(struct acpi_parse_obj_common), |
| 114 | ACPI_MAX_PARSE_CACHE_DEPTH, | 86 | ACPI_MAX_PARSE_CACHE_DEPTH, |
| 115 | &acpi_gbl_ps_node_cache); | 87 | &acpi_gbl_ps_node_cache); |
| @@ -118,7 +90,7 @@ acpi_status acpi_ut_create_caches(void) | |||
| 118 | } | 90 | } |
| 119 | 91 | ||
| 120 | status = | 92 | status = |
| 121 | acpi_os_create_cache("acpi_parse_ext", | 93 | acpi_os_create_cache("Acpi-ParseExt", |
| 122 | sizeof(struct acpi_parse_obj_named), | 94 | sizeof(struct acpi_parse_obj_named), |
| 123 | ACPI_MAX_EXTPARSE_CACHE_DEPTH, | 95 | ACPI_MAX_EXTPARSE_CACHE_DEPTH, |
| 124 | &acpi_gbl_ps_node_ext_cache); | 96 | &acpi_gbl_ps_node_ext_cache); |
| @@ -127,7 +99,7 @@ acpi_status acpi_ut_create_caches(void) | |||
| 127 | } | 99 | } |
| 128 | 100 | ||
| 129 | status = | 101 | status = |
| 130 | acpi_os_create_cache("acpi_operand", | 102 | acpi_os_create_cache("Acpi-Operand", |
| 131 | sizeof(union acpi_operand_object), | 103 | sizeof(union acpi_operand_object), |
| 132 | ACPI_MAX_OBJECT_CACHE_DEPTH, | 104 | ACPI_MAX_OBJECT_CACHE_DEPTH, |
| 133 | &acpi_gbl_operand_cache); | 105 | &acpi_gbl_operand_cache); |
| @@ -135,6 +107,24 @@ acpi_status acpi_ut_create_caches(void) | |||
| 135 | return (status); | 107 | return (status); |
| 136 | } | 108 | } |
| 137 | 109 | ||
| 110 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
| 111 | |||
| 112 | /* Memory allocation lists */ | ||
| 113 | |||
| 114 | status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); | ||
| 115 | if (ACPI_FAILURE(status)) { | ||
| 116 | return (status); | ||
| 117 | } | ||
| 118 | |||
| 119 | status = | ||
| 120 | acpi_ut_create_list("Acpi-Namespace", | ||
| 121 | sizeof(struct acpi_namespace_node), | ||
| 122 | &acpi_gbl_ns_node_list); | ||
| 123 | if (ACPI_FAILURE(status)) { | ||
| 124 | return (status); | ||
| 125 | } | ||
| 126 | #endif | ||
| 127 | |||
| 138 | return (AE_OK); | 128 | return (AE_OK); |
| 139 | } | 129 | } |
| 140 | 130 | ||
| @@ -153,6 +143,9 @@ acpi_status acpi_ut_create_caches(void) | |||
| 153 | acpi_status acpi_ut_delete_caches(void) | 143 | acpi_status acpi_ut_delete_caches(void) |
| 154 | { | 144 | { |
| 155 | 145 | ||
| 146 | (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); | ||
| 147 | acpi_gbl_namespace_cache = NULL; | ||
| 148 | |||
| 156 | (void)acpi_os_delete_cache(acpi_gbl_state_cache); | 149 | (void)acpi_os_delete_cache(acpi_gbl_state_cache); |
| 157 | acpi_gbl_state_cache = NULL; | 150 | acpi_gbl_state_cache = NULL; |
| 158 | 151 | ||
| @@ -165,6 +158,21 @@ acpi_status acpi_ut_delete_caches(void) | |||
| 165 | (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); | 158 | (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); |
| 166 | acpi_gbl_ps_node_ext_cache = NULL; | 159 | acpi_gbl_ps_node_ext_cache = NULL; |
| 167 | 160 | ||
| 161 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
| 162 | |||
| 163 | /* Debug only - display leftover memory allocation, if any */ | ||
| 164 | |||
| 165 | acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); | ||
| 166 | |||
| 167 | /* Free memory lists */ | ||
| 168 | |||
| 169 | acpi_os_free(acpi_gbl_global_list); | ||
| 170 | acpi_gbl_global_list = NULL; | ||
| 171 | |||
| 172 | acpi_os_free(acpi_gbl_ns_node_list); | ||
| 173 | acpi_gbl_ns_node_list = NULL; | ||
| 174 | #endif | ||
| 175 | |||
| 168 | return (AE_OK); | 176 | return (AE_OK); |
| 169 | } | 177 | } |
| 170 | 178 | ||
| @@ -252,7 +260,7 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, | |||
| 252 | 260 | ||
| 253 | /* Allocate a new buffer with local interface to allow tracking */ | 261 | /* Allocate a new buffer with local interface to allow tracking */ |
| 254 | 262 | ||
| 255 | buffer->pointer = ACPI_MEM_CALLOCATE(required_length); | 263 | buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length); |
| 256 | if (!buffer->pointer) { | 264 | if (!buffer->pointer) { |
| 257 | return (AE_NO_MEMORY); | 265 | return (AE_NO_MEMORY); |
| 258 | } | 266 | } |
| @@ -288,7 +296,7 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, | |||
| 288 | * | 296 | * |
| 289 | * RETURN: Address of the allocated memory on success, NULL on failure. | 297 | * RETURN: Address of the allocated memory on success, NULL on failure. |
| 290 | * | 298 | * |
| 291 | * DESCRIPTION: The subsystem's equivalent of malloc. | 299 | * DESCRIPTION: Subsystem equivalent of malloc. |
| 292 | * | 300 | * |
| 293 | ******************************************************************************/ | 301 | ******************************************************************************/ |
| 294 | 302 | ||
| @@ -296,23 +304,23 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) | |||
| 296 | { | 304 | { |
| 297 | void *allocation; | 305 | void *allocation; |
| 298 | 306 | ||
| 299 | ACPI_FUNCTION_TRACE_U32("ut_allocate", size); | 307 | ACPI_FUNCTION_TRACE_U32(ut_allocate, size); |
| 300 | 308 | ||
| 301 | /* Check for an inadvertent size of zero bytes */ | 309 | /* Check for an inadvertent size of zero bytes */ |
| 302 | 310 | ||
| 303 | if (!size) { | 311 | if (!size) { |
| 304 | ACPI_ERROR((module, line, | 312 | ACPI_WARNING((module, line, |
| 305 | "ut_allocate: Attempt to allocate zero bytes, allocating 1 byte")); | 313 | "Attempt to allocate zero bytes, allocating 1 byte")); |
| 306 | size = 1; | 314 | size = 1; |
| 307 | } | 315 | } |
| 308 | 316 | ||
| 309 | allocation = acpi_os_allocate(size); | 317 | allocation = acpi_os_allocate(size); |
| 310 | if (!allocation) { | 318 | if (!allocation) { |
| 319 | |||
| 311 | /* Report allocation error */ | 320 | /* Report allocation error */ |
| 312 | 321 | ||
| 313 | ACPI_ERROR((module, line, | 322 | ACPI_WARNING((module, line, |
| 314 | "ut_allocate: Could not allocate size %X", | 323 | "Could not allocate size %X", (u32) size)); |
| 315 | (u32) size)); | ||
| 316 | 324 | ||
| 317 | return_PTR(NULL); | 325 | return_PTR(NULL); |
| 318 | } | 326 | } |
| @@ -322,7 +330,7 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) | |||
| 322 | 330 | ||
| 323 | /******************************************************************************* | 331 | /******************************************************************************* |
| 324 | * | 332 | * |
| 325 | * FUNCTION: acpi_ut_callocate | 333 | * FUNCTION: acpi_ut_allocate_zeroed |
| 326 | * | 334 | * |
| 327 | * PARAMETERS: Size - Size of the allocation | 335 | * PARAMETERS: Size - Size of the allocation |
| 328 | * Component - Component type of caller | 336 | * Component - Component type of caller |
| @@ -331,542 +339,24 @@ void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line) | |||
| 331 | * | 339 | * |
| 332 | * RETURN: Address of the allocated memory on success, NULL on failure. | 340 | * RETURN: Address of the allocated memory on success, NULL on failure. |
| 333 | * | 341 | * |
| 334 | * DESCRIPTION: Subsystem equivalent of calloc. | 342 | * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. |
| 335 | * | 343 | * |
| 336 | ******************************************************************************/ | 344 | ******************************************************************************/ |
| 337 | 345 | ||
| 338 | void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line) | 346 | void *acpi_ut_allocate_zeroed(acpi_size size, |
| 347 | u32 component, char *module, u32 line) | ||
| 339 | { | 348 | { |
| 340 | void *allocation; | 349 | void *allocation; |
| 341 | 350 | ||
| 342 | ACPI_FUNCTION_TRACE_U32("ut_callocate", size); | ||
| 343 | |||
| 344 | /* Check for an inadvertent size of zero bytes */ | ||
| 345 | |||
| 346 | if (!size) { | ||
| 347 | ACPI_ERROR((module, line, | ||
| 348 | "Attempt to allocate zero bytes, allocating 1 byte")); | ||
| 349 | size = 1; | ||
| 350 | } | ||
| 351 | |||
| 352 | allocation = acpi_os_allocate(size); | ||
| 353 | if (!allocation) { | ||
| 354 | /* Report allocation error */ | ||
| 355 | |||
| 356 | ACPI_ERROR((module, line, | ||
| 357 | "Could not allocate size %X", (u32) size)); | ||
| 358 | return_PTR(NULL); | ||
| 359 | } | ||
| 360 | |||
| 361 | /* Clear the memory block */ | ||
| 362 | |||
| 363 | ACPI_MEMSET(allocation, 0, size); | ||
| 364 | return_PTR(allocation); | ||
| 365 | } | ||
| 366 | |||
| 367 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | ||
| 368 | /* | ||
| 369 | * These procedures are used for tracking memory leaks in the subsystem, and | ||
| 370 | * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. | ||
| 371 | * | ||
| 372 | * Each memory allocation is tracked via a doubly linked list. Each | ||
| 373 | * element contains the caller's component, module name, function name, and | ||
| 374 | * line number. acpi_ut_allocate and acpi_ut_callocate call | ||
| 375 | * acpi_ut_track_allocation to add an element to the list; deletion | ||
| 376 | * occurs in the body of acpi_ut_free. | ||
| 377 | */ | ||
| 378 | |||
| 379 | /******************************************************************************* | ||
| 380 | * | ||
| 381 | * FUNCTION: acpi_ut_create_list | ||
| 382 | * | ||
| 383 | * PARAMETERS: cache_name - Ascii name for the cache | ||
| 384 | * object_size - Size of each cached object | ||
| 385 | * return_cache - Where the new cache object is returned | ||
| 386 | * | ||
| 387 | * RETURN: Status | ||
| 388 | * | ||
| 389 | * DESCRIPTION: Create a local memory list for tracking purposed | ||
| 390 | * | ||
| 391 | ******************************************************************************/ | ||
| 392 | |||
| 393 | static acpi_status | ||
| 394 | acpi_ut_create_list(char *list_name, | ||
| 395 | u16 object_size, struct acpi_memory_list **return_cache) | ||
| 396 | { | ||
| 397 | struct acpi_memory_list *cache; | ||
| 398 | |||
| 399 | cache = acpi_os_allocate(sizeof(struct acpi_memory_list)); | ||
| 400 | if (!cache) { | ||
| 401 | return (AE_NO_MEMORY); | ||
| 402 | } | ||
| 403 | |||
| 404 | ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list)); | ||
| 405 | |||
| 406 | cache->list_name = list_name; | ||
| 407 | cache->object_size = object_size; | ||
| 408 | |||
| 409 | *return_cache = cache; | ||
| 410 | return (AE_OK); | ||
| 411 | } | ||
| 412 | |||
| 413 | /******************************************************************************* | ||
| 414 | * | ||
| 415 | * FUNCTION: acpi_ut_allocate_and_track | ||
| 416 | * | ||
| 417 | * PARAMETERS: Size - Size of the allocation | ||
| 418 | * Component - Component type of caller | ||
| 419 | * Module - Source file name of caller | ||
| 420 | * Line - Line number of caller | ||
| 421 | * | ||
| 422 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
| 423 | * | ||
| 424 | * DESCRIPTION: The subsystem's equivalent of malloc. | ||
| 425 | * | ||
| 426 | ******************************************************************************/ | ||
| 427 | |||
| 428 | void *acpi_ut_allocate_and_track(acpi_size size, | ||
| 429 | u32 component, char *module, u32 line) | ||
| 430 | { | ||
| 431 | struct acpi_debug_mem_block *allocation; | ||
| 432 | acpi_status status; | ||
| 433 | |||
| 434 | allocation = | ||
| 435 | acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header), | ||
| 436 | component, module, line); | ||
| 437 | if (!allocation) { | ||
| 438 | return (NULL); | ||
| 439 | } | ||
| 440 | |||
| 441 | status = acpi_ut_track_allocation(allocation, size, | ||
| 442 | ACPI_MEM_MALLOC, component, module, | ||
| 443 | line); | ||
| 444 | if (ACPI_FAILURE(status)) { | ||
| 445 | acpi_os_free(allocation); | ||
| 446 | return (NULL); | ||
| 447 | } | ||
| 448 | |||
| 449 | acpi_gbl_global_list->total_allocated++; | ||
| 450 | acpi_gbl_global_list->current_total_size += (u32) size; | ||
| 451 | |||
| 452 | return ((void *)&allocation->user_space); | ||
| 453 | } | ||
| 454 | |||
| 455 | /******************************************************************************* | ||
| 456 | * | ||
| 457 | * FUNCTION: acpi_ut_callocate_and_track | ||
| 458 | * | ||
| 459 | * PARAMETERS: Size - Size of the allocation | ||
| 460 | * Component - Component type of caller | ||
| 461 | * Module - Source file name of caller | ||
| 462 | * Line - Line number of caller | ||
| 463 | * | ||
| 464 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
| 465 | * | ||
| 466 | * DESCRIPTION: Subsystem equivalent of calloc. | ||
| 467 | * | ||
| 468 | ******************************************************************************/ | ||
| 469 | |||
| 470 | void *acpi_ut_callocate_and_track(acpi_size size, | ||
| 471 | u32 component, char *module, u32 line) | ||
| 472 | { | ||
| 473 | struct acpi_debug_mem_block *allocation; | ||
| 474 | acpi_status status; | ||
| 475 | |||
| 476 | allocation = | ||
| 477 | acpi_ut_callocate(size + sizeof(struct acpi_debug_mem_header), | ||
| 478 | component, module, line); | ||
| 479 | if (!allocation) { | ||
| 480 | /* Report allocation error */ | ||
| 481 | |||
| 482 | ACPI_ERROR((module, line, | ||
| 483 | "Could not allocate size %X", (u32) size)); | ||
| 484 | return (NULL); | ||
| 485 | } | ||
| 486 | |||
| 487 | status = acpi_ut_track_allocation(allocation, size, | ||
| 488 | ACPI_MEM_CALLOC, component, module, | ||
| 489 | line); | ||
| 490 | if (ACPI_FAILURE(status)) { | ||
| 491 | acpi_os_free(allocation); | ||
| 492 | return (NULL); | ||
| 493 | } | ||
| 494 | |||
| 495 | acpi_gbl_global_list->total_allocated++; | ||
| 496 | acpi_gbl_global_list->current_total_size += (u32) size; | ||
| 497 | |||
| 498 | return ((void *)&allocation->user_space); | ||
| 499 | } | ||
| 500 | |||
| 501 | /******************************************************************************* | ||
| 502 | * | ||
| 503 | * FUNCTION: acpi_ut_free_and_track | ||
| 504 | * | ||
| 505 | * PARAMETERS: Allocation - Address of the memory to deallocate | ||
| 506 | * Component - Component type of caller | ||
| 507 | * Module - Source file name of caller | ||
| 508 | * Line - Line number of caller | ||
| 509 | * | ||
| 510 | * RETURN: None | ||
| 511 | * | ||
| 512 | * DESCRIPTION: Frees the memory at Allocation | ||
| 513 | * | ||
| 514 | ******************************************************************************/ | ||
| 515 | |||
| 516 | void | ||
| 517 | acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line) | ||
| 518 | { | ||
| 519 | struct acpi_debug_mem_block *debug_block; | ||
| 520 | acpi_status status; | ||
| 521 | |||
| 522 | ACPI_FUNCTION_TRACE_PTR("ut_free", allocation); | ||
| 523 | |||
| 524 | if (NULL == allocation) { | ||
| 525 | ACPI_ERROR((module, line, "Attempt to delete a NULL address")); | ||
| 526 | |||
| 527 | return_VOID; | ||
| 528 | } | ||
| 529 | |||
| 530 | debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block, | ||
| 531 | (((char *)allocation) - | ||
| 532 | sizeof(struct acpi_debug_mem_header))); | ||
| 533 | |||
| 534 | acpi_gbl_global_list->total_freed++; | ||
| 535 | acpi_gbl_global_list->current_total_size -= debug_block->size; | ||
| 536 | |||
| 537 | status = acpi_ut_remove_allocation(debug_block, | ||
| 538 | component, module, line); | ||
| 539 | if (ACPI_FAILURE(status)) { | ||
| 540 | ACPI_EXCEPTION((AE_INFO, status, "Could not free memory")); | ||
| 541 | } | ||
| 542 | |||
| 543 | acpi_os_free(debug_block); | ||
| 544 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); | ||
| 545 | return_VOID; | ||
| 546 | } | ||
| 547 | |||
| 548 | /******************************************************************************* | ||
| 549 | * | ||
| 550 | * FUNCTION: acpi_ut_find_allocation | ||
| 551 | * | ||
| 552 | * PARAMETERS: Allocation - Address of allocated memory | ||
| 553 | * | ||
| 554 | * RETURN: A list element if found; NULL otherwise. | ||
| 555 | * | ||
| 556 | * DESCRIPTION: Searches for an element in the global allocation tracking list. | ||
| 557 | * | ||
| 558 | ******************************************************************************/ | ||
| 559 | |||
| 560 | static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) | ||
| 561 | { | ||
| 562 | struct acpi_debug_mem_block *element; | ||
| 563 | |||
| 564 | ACPI_FUNCTION_ENTRY(); | 351 | ACPI_FUNCTION_ENTRY(); |
| 565 | 352 | ||
| 566 | element = acpi_gbl_global_list->list_head; | 353 | allocation = acpi_ut_allocate(size, component, module, line); |
| 567 | 354 | if (allocation) { | |
| 568 | /* Search for the address. */ | ||
| 569 | |||
| 570 | while (element) { | ||
| 571 | if (element == allocation) { | ||
| 572 | return (element); | ||
| 573 | } | ||
| 574 | |||
| 575 | element = element->next; | ||
| 576 | } | ||
| 577 | |||
| 578 | return (NULL); | ||
| 579 | } | ||
| 580 | |||
| 581 | /******************************************************************************* | ||
| 582 | * | ||
| 583 | * FUNCTION: acpi_ut_track_allocation | ||
| 584 | * | ||
| 585 | * PARAMETERS: Allocation - Address of allocated memory | ||
| 586 | * Size - Size of the allocation | ||
| 587 | * alloc_type - MEM_MALLOC or MEM_CALLOC | ||
| 588 | * Component - Component type of caller | ||
| 589 | * Module - Source file name of caller | ||
| 590 | * Line - Line number of caller | ||
| 591 | * | ||
| 592 | * RETURN: None. | ||
| 593 | * | ||
| 594 | * DESCRIPTION: Inserts an element into the global allocation tracking list. | ||
| 595 | * | ||
| 596 | ******************************************************************************/ | ||
| 597 | |||
| 598 | static acpi_status | ||
| 599 | acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, | ||
| 600 | acpi_size size, | ||
| 601 | u8 alloc_type, u32 component, char *module, u32 line) | ||
| 602 | { | ||
| 603 | struct acpi_memory_list *mem_list; | ||
| 604 | struct acpi_debug_mem_block *element; | ||
| 605 | acpi_status status = AE_OK; | ||
| 606 | |||
| 607 | ACPI_FUNCTION_TRACE_PTR("ut_track_allocation", allocation); | ||
| 608 | |||
| 609 | mem_list = acpi_gbl_global_list; | ||
| 610 | status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY); | ||
| 611 | if (ACPI_FAILURE(status)) { | ||
| 612 | return_ACPI_STATUS(status); | ||
| 613 | } | ||
| 614 | |||
| 615 | /* | ||
| 616 | * Search list for this address to make sure it is not already on the list. | ||
| 617 | * This will catch several kinds of problems. | ||
| 618 | */ | ||
| 619 | element = acpi_ut_find_allocation(allocation); | ||
| 620 | if (element) { | ||
| 621 | ACPI_ERROR((AE_INFO, | ||
| 622 | "ut_track_allocation: Allocation already present in list! (%p)", | ||
| 623 | allocation)); | ||
| 624 | |||
| 625 | ACPI_ERROR((AE_INFO, "Element %p Address %p", | ||
| 626 | element, allocation)); | ||
| 627 | |||
| 628 | goto unlock_and_exit; | ||
| 629 | } | ||
| 630 | |||
| 631 | /* Fill in the instance data. */ | ||
| 632 | |||
| 633 | allocation->size = (u32) size; | ||
| 634 | allocation->alloc_type = alloc_type; | ||
| 635 | allocation->component = component; | ||
| 636 | allocation->line = line; | ||
| 637 | |||
| 638 | ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME); | ||
| 639 | allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0; | ||
| 640 | |||
| 641 | /* Insert at list head */ | ||
| 642 | |||
| 643 | if (mem_list->list_head) { | ||
| 644 | ((struct acpi_debug_mem_block *)(mem_list->list_head))-> | ||
| 645 | previous = allocation; | ||
| 646 | } | ||
| 647 | |||
| 648 | allocation->next = mem_list->list_head; | ||
| 649 | allocation->previous = NULL; | ||
| 650 | |||
| 651 | mem_list->list_head = allocation; | ||
| 652 | |||
| 653 | unlock_and_exit: | ||
| 654 | status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); | ||
| 655 | return_ACPI_STATUS(status); | ||
| 656 | } | ||
| 657 | |||
| 658 | /******************************************************************************* | ||
| 659 | * | ||
| 660 | * FUNCTION: acpi_ut_remove_allocation | ||
| 661 | * | ||
| 662 | * PARAMETERS: Allocation - Address of allocated memory | ||
| 663 | * Component - Component type of caller | ||
| 664 | * Module - Source file name of caller | ||
| 665 | * Line - Line number of caller | ||
| 666 | * | ||
| 667 | * RETURN: | ||
| 668 | * | ||
| 669 | * DESCRIPTION: Deletes an element from the global allocation tracking list. | ||
| 670 | * | ||
| 671 | ******************************************************************************/ | ||
| 672 | |||
| 673 | static acpi_status | ||
| 674 | acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation, | ||
| 675 | u32 component, char *module, u32 line) | ||
| 676 | { | ||
| 677 | struct acpi_memory_list *mem_list; | ||
| 678 | acpi_status status; | ||
| 679 | |||
| 680 | ACPI_FUNCTION_TRACE("ut_remove_allocation"); | ||
| 681 | |||
| 682 | mem_list = acpi_gbl_global_list; | ||
| 683 | if (NULL == mem_list->list_head) { | ||
| 684 | /* No allocations! */ | ||
| 685 | |||
| 686 | ACPI_ERROR((module, line, | ||
| 687 | "Empty allocation list, nothing to free!")); | ||
| 688 | |||
| 689 | return_ACPI_STATUS(AE_OK); | ||
| 690 | } | ||
| 691 | |||
| 692 | status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY); | ||
| 693 | if (ACPI_FAILURE(status)) { | ||
| 694 | return_ACPI_STATUS(status); | ||
| 695 | } | ||
| 696 | |||
| 697 | /* Unlink */ | ||
| 698 | |||
| 699 | if (allocation->previous) { | ||
| 700 | (allocation->previous)->next = allocation->next; | ||
| 701 | } else { | ||
| 702 | mem_list->list_head = allocation->next; | ||
| 703 | } | ||
| 704 | |||
| 705 | if (allocation->next) { | ||
| 706 | (allocation->next)->previous = allocation->previous; | ||
| 707 | } | ||
| 708 | |||
| 709 | /* Mark the segment as deleted */ | ||
| 710 | |||
| 711 | ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size); | ||
| 712 | |||
| 713 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", | ||
| 714 | allocation->size)); | ||
| 715 | 355 | ||
| 716 | status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); | 356 | /* Clear the memory block */ |
| 717 | return_ACPI_STATUS(status); | ||
| 718 | } | ||
| 719 | |||
| 720 | /******************************************************************************* | ||
| 721 | * | ||
| 722 | * FUNCTION: acpi_ut_dump_allocation_info | ||
| 723 | * | ||
| 724 | * PARAMETERS: | ||
| 725 | * | ||
| 726 | * RETURN: None | ||
| 727 | * | ||
| 728 | * DESCRIPTION: Print some info about the outstanding allocations. | ||
| 729 | * | ||
| 730 | ******************************************************************************/ | ||
| 731 | 357 | ||
| 732 | #ifdef ACPI_FUTURE_USAGE | 358 | ACPI_MEMSET(allocation, 0, size); |
| 733 | void acpi_ut_dump_allocation_info(void) | ||
| 734 | { | ||
| 735 | /* | ||
| 736 | struct acpi_memory_list *mem_list; | ||
| 737 | */ | ||
| 738 | |||
| 739 | ACPI_FUNCTION_TRACE("ut_dump_allocation_info"); | ||
| 740 | |||
| 741 | /* | ||
| 742 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
| 743 | ("%30s: %4d (%3d Kb)\n", "Current allocations", | ||
| 744 | mem_list->current_count, | ||
| 745 | ROUND_UP_TO_1K (mem_list->current_size))); | ||
| 746 | |||
| 747 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
| 748 | ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", | ||
| 749 | mem_list->max_concurrent_count, | ||
| 750 | ROUND_UP_TO_1K (mem_list->max_concurrent_size))); | ||
| 751 | |||
| 752 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
| 753 | ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", | ||
| 754 | running_object_count, | ||
| 755 | ROUND_UP_TO_1K (running_object_size))); | ||
| 756 | |||
| 757 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
| 758 | ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", | ||
| 759 | running_alloc_count, | ||
| 760 | ROUND_UP_TO_1K (running_alloc_size))); | ||
| 761 | |||
| 762 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
| 763 | ("%30s: %4d (%3d Kb)\n", "Current Nodes", | ||
| 764 | acpi_gbl_current_node_count, | ||
| 765 | ROUND_UP_TO_1K (acpi_gbl_current_node_size))); | ||
| 766 | |||
| 767 | ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, | ||
| 768 | ("%30s: %4d (%3d Kb)\n", "Max Nodes", | ||
| 769 | acpi_gbl_max_concurrent_node_count, | ||
| 770 | ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * | ||
| 771 | sizeof (struct acpi_namespace_node))))); | ||
| 772 | */ | ||
| 773 | return_VOID; | ||
| 774 | } | ||
| 775 | #endif /* ACPI_FUTURE_USAGE */ | ||
| 776 | |||
| 777 | /******************************************************************************* | ||
| 778 | * | ||
| 779 | * FUNCTION: acpi_ut_dump_allocations | ||
| 780 | * | ||
| 781 | * PARAMETERS: Component - Component(s) to dump info for. | ||
| 782 | * Module - Module to dump info for. NULL means all. | ||
| 783 | * | ||
| 784 | * RETURN: None | ||
| 785 | * | ||
| 786 | * DESCRIPTION: Print a list of all outstanding allocations. | ||
| 787 | * | ||
| 788 | ******************************************************************************/ | ||
| 789 | |||
| 790 | void acpi_ut_dump_allocations(u32 component, char *module) | ||
| 791 | { | ||
| 792 | struct acpi_debug_mem_block *element; | ||
| 793 | union acpi_descriptor *descriptor; | ||
| 794 | u32 num_outstanding = 0; | ||
| 795 | |||
| 796 | ACPI_FUNCTION_TRACE("ut_dump_allocations"); | ||
| 797 | |||
| 798 | /* | ||
| 799 | * Walk the allocation list. | ||
| 800 | */ | ||
| 801 | if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) { | ||
| 802 | return; | ||
| 803 | } | 359 | } |
| 804 | 360 | ||
| 805 | element = acpi_gbl_global_list->list_head; | 361 | return (allocation); |
| 806 | while (element) { | ||
| 807 | if ((element->component & component) && | ||
| 808 | ((module == NULL) | ||
| 809 | || (0 == ACPI_STRCMP(module, element->module)))) { | ||
| 810 | /* Ignore allocated objects that are in a cache */ | ||
| 811 | |||
| 812 | descriptor = | ||
| 813 | ACPI_CAST_PTR(union acpi_descriptor, | ||
| 814 | &element->user_space); | ||
| 815 | if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { | ||
| 816 | acpi_os_printf("%p Len %04X %9.9s-%d [%s] ", | ||
| 817 | descriptor, element->size, | ||
| 818 | element->module, element->line, | ||
| 819 | acpi_ut_get_descriptor_name | ||
| 820 | (descriptor)); | ||
| 821 | |||
| 822 | /* Most of the elements will be Operand objects. */ | ||
| 823 | |||
| 824 | switch (ACPI_GET_DESCRIPTOR_TYPE(descriptor)) { | ||
| 825 | case ACPI_DESC_TYPE_OPERAND: | ||
| 826 | acpi_os_printf("%12.12s R%hd", | ||
| 827 | acpi_ut_get_type_name | ||
| 828 | (descriptor->object. | ||
| 829 | common.type), | ||
| 830 | descriptor->object. | ||
| 831 | common.reference_count); | ||
| 832 | break; | ||
| 833 | |||
| 834 | case ACPI_DESC_TYPE_PARSER: | ||
| 835 | acpi_os_printf("aml_opcode %04hX", | ||
| 836 | descriptor->op.asl. | ||
| 837 | aml_opcode); | ||
| 838 | break; | ||
| 839 | |||
| 840 | case ACPI_DESC_TYPE_NAMED: | ||
| 841 | acpi_os_printf("%4.4s", | ||
| 842 | acpi_ut_get_node_name | ||
| 843 | (&descriptor->node)); | ||
| 844 | break; | ||
| 845 | |||
| 846 | default: | ||
| 847 | break; | ||
| 848 | } | ||
| 849 | |||
| 850 | acpi_os_printf("\n"); | ||
| 851 | num_outstanding++; | ||
| 852 | } | ||
| 853 | } | ||
| 854 | element = element->next; | ||
| 855 | } | ||
| 856 | |||
| 857 | (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY); | ||
| 858 | |||
| 859 | /* Print summary */ | ||
| 860 | |||
| 861 | if (!num_outstanding) { | ||
| 862 | ACPI_INFO((AE_INFO, "No outstanding allocations")); | ||
| 863 | } else { | ||
| 864 | ACPI_ERROR((AE_INFO, | ||
| 865 | "%d(%X) Outstanding allocations", | ||
| 866 | num_outstanding, num_outstanding)); | ||
| 867 | } | ||
| 868 | |||
| 869 | return_VOID; | ||
| 870 | } | 362 | } |
| 871 | |||
| 872 | #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ | ||
