Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.12 988 lines 27 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: utalloc - local cache and memory allocation routines 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2005, R. Byron Moore 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 45#include <acpi/acpi.h> 46 47#define _COMPONENT ACPI_UTILITIES 48 ACPI_MODULE_NAME ("utalloc") 49 50 51/****************************************************************************** 52 * 53 * FUNCTION: acpi_ut_release_to_cache 54 * 55 * PARAMETERS: list_id - Memory list/cache ID 56 * Object - The object to be released 57 * 58 * RETURN: None 59 * 60 * DESCRIPTION: Release an object to the specified cache. If cache is full, 61 * the object is deleted. 62 * 63 ******************************************************************************/ 64 65void 66acpi_ut_release_to_cache ( 67 u32 list_id, 68 void *object) 69{ 70 struct acpi_memory_list *cache_info; 71 72 73 ACPI_FUNCTION_ENTRY (); 74 75 76 cache_info = &acpi_gbl_memory_lists[list_id]; 77 78#ifdef ACPI_ENABLE_OBJECT_CACHE 79 80 /* If walk cache is full, just free this wallkstate object */ 81 82 if (cache_info->cache_depth >= cache_info->max_cache_depth) { 83 ACPI_MEM_FREE (object); 84 ACPI_MEM_TRACKING (cache_info->total_freed++); 85 } 86 87 /* Otherwise put this object back into the cache */ 88 89 else { 90 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { 91 return; 92 } 93 94 /* Mark the object as cached */ 95 96 ACPI_MEMSET (object, 0xCA, cache_info->object_size); 97 ACPI_SET_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_CACHED); 98 99 /* Put the object at the head of the cache list */ 100 101 * (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head; 102 cache_info->list_head = object; 103 cache_info->cache_depth++; 104 105 (void) acpi_ut_release_mutex (ACPI_MTX_CACHES); 106 } 107 108#else 109 110 /* Object cache is disabled; just free the object */ 111 112 ACPI_MEM_FREE (object); 113 ACPI_MEM_TRACKING (cache_info->total_freed++); 114#endif 115} 116 117 118/****************************************************************************** 119 * 120 * FUNCTION: acpi_ut_acquire_from_cache 121 * 122 * PARAMETERS: list_id - Memory list ID 123 * 124 * RETURN: A requested object. NULL if the object could not be 125 * allocated. 126 * 127 * DESCRIPTION: Get an object from the specified cache. If cache is empty, 128 * the object is allocated. 129 * 130 ******************************************************************************/ 131 132void * 133acpi_ut_acquire_from_cache ( 134 u32 list_id) 135{ 136 struct acpi_memory_list *cache_info; 137 void *object; 138 139 140 ACPI_FUNCTION_NAME ("ut_acquire_from_cache"); 141 142 143 cache_info = &acpi_gbl_memory_lists[list_id]; 144 145#ifdef ACPI_ENABLE_OBJECT_CACHE 146 147 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_CACHES))) { 148 return (NULL); 149 } 150 151 ACPI_MEM_TRACKING (cache_info->cache_requests++); 152 153 /* Check the cache first */ 154 155 if (cache_info->list_head) { 156 /* There is an object available, use it */ 157 158 object = cache_info->list_head; 159 cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))); 160 161 ACPI_MEM_TRACKING (cache_info->cache_hits++); 162 cache_info->cache_depth--; 163 164#ifdef ACPI_DBG_TRACK_ALLOCATIONS 165 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p from %s\n", 166 object, acpi_gbl_memory_lists[list_id].list_name)); 167#endif 168 169 if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { 170 return (NULL); 171 } 172 173 /* Clear (zero) the previously used Object */ 174 175 ACPI_MEMSET (object, 0, cache_info->object_size); 176 } 177 178 else { 179 /* The cache is empty, create a new object */ 180 181 /* Avoid deadlock with ACPI_MEM_CALLOCATE */ 182 183 if (ACPI_FAILURE (acpi_ut_release_mutex (ACPI_MTX_CACHES))) { 184 return (NULL); 185 } 186 187 object = ACPI_MEM_CALLOCATE (cache_info->object_size); 188 ACPI_MEM_TRACKING (cache_info->total_allocated++); 189 } 190 191#else 192 193 /* Object cache is disabled; just allocate the object */ 194 195 object = ACPI_MEM_CALLOCATE (cache_info->object_size); 196 ACPI_MEM_TRACKING (cache_info->total_allocated++); 197#endif 198 199 return (object); 200} 201 202 203#ifdef ACPI_ENABLE_OBJECT_CACHE 204/****************************************************************************** 205 * 206 * FUNCTION: acpi_ut_delete_generic_cache 207 * 208 * PARAMETERS: list_id - Memory list ID 209 * 210 * RETURN: None 211 * 212 * DESCRIPTION: Free all objects within the requested cache. 213 * 214 ******************************************************************************/ 215 216void 217acpi_ut_delete_generic_cache ( 218 u32 list_id) 219{ 220 struct acpi_memory_list *cache_info; 221 char *next; 222 223 224 ACPI_FUNCTION_ENTRY (); 225 226 227 cache_info = &acpi_gbl_memory_lists[list_id]; 228 while (cache_info->list_head) { 229 /* Delete one cached state object */ 230 231 next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset]))); 232 ACPI_MEM_FREE (cache_info->list_head); 233 234 cache_info->list_head = next; 235 cache_info->cache_depth--; 236 } 237} 238#endif 239 240 241/******************************************************************************* 242 * 243 * FUNCTION: acpi_ut_validate_buffer 244 * 245 * PARAMETERS: Buffer - Buffer descriptor to be validated 246 * 247 * RETURN: Status 248 * 249 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer 250 * 251 ******************************************************************************/ 252 253acpi_status 254acpi_ut_validate_buffer ( 255 struct acpi_buffer *buffer) 256{ 257 258 /* Obviously, the structure pointer must be valid */ 259 260 if (!buffer) { 261 return (AE_BAD_PARAMETER); 262 } 263 264 /* Special semantics for the length */ 265 266 if ((buffer->length == ACPI_NO_BUFFER) || 267 (buffer->length == ACPI_ALLOCATE_BUFFER) || 268 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) { 269 return (AE_OK); 270 } 271 272 /* Length is valid, the buffer pointer must be also */ 273 274 if (!buffer->pointer) { 275 return (AE_BAD_PARAMETER); 276 } 277 278 return (AE_OK); 279} 280 281 282/******************************************************************************* 283 * 284 * FUNCTION: acpi_ut_initialize_buffer 285 * 286 * PARAMETERS: Buffer - Buffer to be validated 287 * required_length - Length needed 288 * 289 * RETURN: Status 290 * 291 * DESCRIPTION: Validate that the buffer is of the required length or 292 * allocate a new buffer. Returned buffer is always zeroed. 293 * 294 ******************************************************************************/ 295 296acpi_status 297acpi_ut_initialize_buffer ( 298 struct acpi_buffer *buffer, 299 acpi_size required_length) 300{ 301 acpi_status status = AE_OK; 302 303 304 switch (buffer->length) { 305 case ACPI_NO_BUFFER: 306 307 /* Set the exception and returned the required length */ 308 309 status = AE_BUFFER_OVERFLOW; 310 break; 311 312 313 case ACPI_ALLOCATE_BUFFER: 314 315 /* Allocate a new buffer */ 316 317 buffer->pointer = acpi_os_allocate (required_length); 318 if (!buffer->pointer) { 319 return (AE_NO_MEMORY); 320 } 321 322 /* Clear the buffer */ 323 324 ACPI_MEMSET (buffer->pointer, 0, required_length); 325 break; 326 327 328 case ACPI_ALLOCATE_LOCAL_BUFFER: 329 330 /* Allocate a new buffer with local interface to allow tracking */ 331 332 buffer->pointer = ACPI_MEM_CALLOCATE (required_length); 333 if (!buffer->pointer) { 334 return (AE_NO_MEMORY); 335 } 336 break; 337 338 339 default: 340 341 /* Existing buffer: Validate the size of the buffer */ 342 343 if (buffer->length < required_length) { 344 status = AE_BUFFER_OVERFLOW; 345 break; 346 } 347 348 /* Clear the buffer */ 349 350 ACPI_MEMSET (buffer->pointer, 0, required_length); 351 break; 352 } 353 354 buffer->length = required_length; 355 return (status); 356} 357 358 359/******************************************************************************* 360 * 361 * FUNCTION: acpi_ut_allocate 362 * 363 * PARAMETERS: Size - Size of the allocation 364 * Component - Component type of caller 365 * Module - Source file name of caller 366 * Line - Line number of caller 367 * 368 * RETURN: Address of the allocated memory on success, NULL on failure. 369 * 370 * DESCRIPTION: The subsystem's equivalent of malloc. 371 * 372 ******************************************************************************/ 373 374void * 375acpi_ut_allocate ( 376 acpi_size size, 377 u32 component, 378 char *module, 379 u32 line) 380{ 381 void *allocation; 382 383 384 ACPI_FUNCTION_TRACE_U32 ("ut_allocate", size); 385 386 387 /* Check for an inadvertent size of zero bytes */ 388 389 if (!size) { 390 _ACPI_REPORT_ERROR (module, line, component, 391 ("ut_allocate: Attempt to allocate zero bytes\n")); 392 size = 1; 393 } 394 395 allocation = acpi_os_allocate (size); 396 if (!allocation) { 397 /* Report allocation error */ 398 399 _ACPI_REPORT_ERROR (module, line, component, 400 ("ut_allocate: Could not allocate size %X\n", (u32) size)); 401 402 return_PTR (NULL); 403 } 404 405 return_PTR (allocation); 406} 407 408 409/******************************************************************************* 410 * 411 * FUNCTION: acpi_ut_callocate 412 * 413 * PARAMETERS: Size - Size of the allocation 414 * Component - Component type of caller 415 * Module - Source file name of caller 416 * Line - Line number of caller 417 * 418 * RETURN: Address of the allocated memory on success, NULL on failure. 419 * 420 * DESCRIPTION: Subsystem equivalent of calloc. 421 * 422 ******************************************************************************/ 423 424void * 425acpi_ut_callocate ( 426 acpi_size size, 427 u32 component, 428 char *module, 429 u32 line) 430{ 431 void *allocation; 432 433 434 ACPI_FUNCTION_TRACE_U32 ("ut_callocate", size); 435 436 437 /* Check for an inadvertent size of zero bytes */ 438 439 if (!size) { 440 _ACPI_REPORT_ERROR (module, line, component, 441 ("ut_callocate: Attempt to allocate zero bytes\n")); 442 return_PTR (NULL); 443 } 444 445 allocation = acpi_os_allocate (size); 446 if (!allocation) { 447 /* Report allocation error */ 448 449 _ACPI_REPORT_ERROR (module, line, component, 450 ("ut_callocate: Could not allocate size %X\n", (u32) size)); 451 return_PTR (NULL); 452 } 453 454 /* Clear the memory block */ 455 456 ACPI_MEMSET (allocation, 0, size); 457 return_PTR (allocation); 458} 459 460 461#ifdef ACPI_DBG_TRACK_ALLOCATIONS 462/* 463 * These procedures are used for tracking memory leaks in the subsystem, and 464 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. 465 * 466 * Each memory allocation is tracked via a doubly linked list. Each 467 * element contains the caller's component, module name, function name, and 468 * line number. acpi_ut_allocate and acpi_ut_callocate call 469 * acpi_ut_track_allocation to add an element to the list; deletion 470 * occurs in the body of acpi_ut_free. 471 */ 472 473 474/******************************************************************************* 475 * 476 * FUNCTION: acpi_ut_allocate_and_track 477 * 478 * PARAMETERS: Size - Size of the allocation 479 * Component - Component type of caller 480 * Module - Source file name of caller 481 * Line - Line number of caller 482 * 483 * RETURN: Address of the allocated memory on success, NULL on failure. 484 * 485 * DESCRIPTION: The subsystem's equivalent of malloc. 486 * 487 ******************************************************************************/ 488 489void * 490acpi_ut_allocate_and_track ( 491 acpi_size size, 492 u32 component, 493 char *module, 494 u32 line) 495{ 496 struct acpi_debug_mem_block *allocation; 497 acpi_status status; 498 499 500 allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component, 501 module, line); 502 if (!allocation) { 503 return (NULL); 504 } 505 506 status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, 507 ACPI_MEM_MALLOC, component, module, line); 508 if (ACPI_FAILURE (status)) { 509 acpi_os_free (allocation); 510 return (NULL); 511 } 512 513 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; 514 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; 515 516 return ((void *) &allocation->user_space); 517} 518 519 520/******************************************************************************* 521 * 522 * FUNCTION: acpi_ut_callocate_and_track 523 * 524 * PARAMETERS: Size - Size of the allocation 525 * Component - Component type of caller 526 * Module - Source file name of caller 527 * Line - Line number of caller 528 * 529 * RETURN: Address of the allocated memory on success, NULL on failure. 530 * 531 * DESCRIPTION: Subsystem equivalent of calloc. 532 * 533 ******************************************************************************/ 534 535void * 536acpi_ut_callocate_and_track ( 537 acpi_size size, 538 u32 component, 539 char *module, 540 u32 line) 541{ 542 struct acpi_debug_mem_block *allocation; 543 acpi_status status; 544 545 546 allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component, 547 module, line); 548 if (!allocation) { 549 /* Report allocation error */ 550 551 _ACPI_REPORT_ERROR (module, line, component, 552 ("ut_callocate: Could not allocate size %X\n", (u32) size)); 553 return (NULL); 554 } 555 556 status = acpi_ut_track_allocation (ACPI_MEM_LIST_GLOBAL, allocation, size, 557 ACPI_MEM_CALLOC, component, module, line); 558 if (ACPI_FAILURE (status)) { 559 acpi_os_free (allocation); 560 return (NULL); 561 } 562 563 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_allocated++; 564 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size += (u32) size; 565 566 return ((void *) &allocation->user_space); 567} 568 569 570/******************************************************************************* 571 * 572 * FUNCTION: acpi_ut_free_and_track 573 * 574 * PARAMETERS: Allocation - Address of the memory to deallocate 575 * Component - Component type of caller 576 * Module - Source file name of caller 577 * Line - Line number of caller 578 * 579 * RETURN: None 580 * 581 * DESCRIPTION: Frees the memory at Allocation 582 * 583 ******************************************************************************/ 584 585void 586acpi_ut_free_and_track ( 587 void *allocation, 588 u32 component, 589 char *module, 590 u32 line) 591{ 592 struct acpi_debug_mem_block *debug_block; 593 acpi_status status; 594 595 596 ACPI_FUNCTION_TRACE_PTR ("ut_free", allocation); 597 598 599 if (NULL == allocation) { 600 _ACPI_REPORT_ERROR (module, line, component, 601 ("acpi_ut_free: Attempt to delete a NULL address\n")); 602 603 return_VOID; 604 } 605 606 debug_block = ACPI_CAST_PTR (struct acpi_debug_mem_block, 607 (((char *) allocation) - sizeof (struct acpi_debug_mem_header))); 608 609 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].total_freed++; 610 acpi_gbl_memory_lists[ACPI_MEM_LIST_GLOBAL].current_total_size -= debug_block->size; 611 612 status = acpi_ut_remove_allocation (ACPI_MEM_LIST_GLOBAL, debug_block, 613 component, module, line); 614 if (ACPI_FAILURE (status)) { 615 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not free memory, %s\n", 616 acpi_format_exception (status))); 617 } 618 619 acpi_os_free (debug_block); 620 621 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); 622 623 return_VOID; 624} 625 626 627/******************************************************************************* 628 * 629 * FUNCTION: acpi_ut_find_allocation 630 * 631 * PARAMETERS: list_id - Memory list to search 632 * Allocation - Address of allocated memory 633 * 634 * RETURN: A list element if found; NULL otherwise. 635 * 636 * DESCRIPTION: Searches for an element in the global allocation tracking list. 637 * 638 ******************************************************************************/ 639 640struct acpi_debug_mem_block * 641acpi_ut_find_allocation ( 642 u32 list_id, 643 void *allocation) 644{ 645 struct acpi_debug_mem_block *element; 646 647 648 ACPI_FUNCTION_ENTRY (); 649 650 651 if (list_id > ACPI_MEM_LIST_MAX) { 652 return (NULL); 653 } 654 655 element = acpi_gbl_memory_lists[list_id].list_head; 656 657 /* Search for the address. */ 658 659 while (element) { 660 if (element == allocation) { 661 return (element); 662 } 663 664 element = element->next; 665 } 666 667 return (NULL); 668} 669 670 671/******************************************************************************* 672 * 673 * FUNCTION: acpi_ut_track_allocation 674 * 675 * PARAMETERS: list_id - Memory list to search 676 * Allocation - Address of allocated memory 677 * Size - Size of the allocation 678 * alloc_type - MEM_MALLOC or MEM_CALLOC 679 * Component - Component type of caller 680 * Module - Source file name of caller 681 * Line - Line number of caller 682 * 683 * RETURN: None. 684 * 685 * DESCRIPTION: Inserts an element into the global allocation tracking list. 686 * 687 ******************************************************************************/ 688 689acpi_status 690acpi_ut_track_allocation ( 691 u32 list_id, 692 struct acpi_debug_mem_block *allocation, 693 acpi_size size, 694 u8 alloc_type, 695 u32 component, 696 char *module, 697 u32 line) 698{ 699 struct acpi_memory_list *mem_list; 700 struct acpi_debug_mem_block *element; 701 acpi_status status = AE_OK; 702 703 704 ACPI_FUNCTION_TRACE_PTR ("ut_track_allocation", allocation); 705 706 707 if (list_id > ACPI_MEM_LIST_MAX) { 708 return_ACPI_STATUS (AE_BAD_PARAMETER); 709 } 710 711 mem_list = &acpi_gbl_memory_lists[list_id]; 712 status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); 713 if (ACPI_FAILURE (status)) { 714 return_ACPI_STATUS (status); 715 } 716 717 /* 718 * Search list for this address to make sure it is not already on the list. 719 * This will catch several kinds of problems. 720 */ 721 722 element = acpi_ut_find_allocation (list_id, allocation); 723 if (element) { 724 ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n", 725 allocation)); 726 727 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation)); 728 729 goto unlock_and_exit; 730 } 731 732 /* Fill in the instance data. */ 733 734 allocation->size = (u32) size; 735 allocation->alloc_type = alloc_type; 736 allocation->component = component; 737 allocation->line = line; 738 739 ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME); 740 allocation->module[ACPI_MAX_MODULE_NAME-1] = 0; 741 742 /* Insert at list head */ 743 744 if (mem_list->list_head) { 745 ((struct acpi_debug_mem_block *)(mem_list->list_head))->previous = allocation; 746 } 747 748 allocation->next = mem_list->list_head; 749 allocation->previous = NULL; 750 751 mem_list->list_head = allocation; 752 753 754unlock_and_exit: 755 status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); 756 return_ACPI_STATUS (status); 757} 758 759 760/******************************************************************************* 761 * 762 * FUNCTION: acpi_ut_remove_allocation 763 * 764 * PARAMETERS: list_id - Memory list to search 765 * Allocation - Address of allocated memory 766 * Component - Component type of caller 767 * Module - Source file name of caller 768 * Line - Line number of caller 769 * 770 * RETURN: 771 * 772 * DESCRIPTION: Deletes an element from the global allocation tracking list. 773 * 774 ******************************************************************************/ 775 776acpi_status 777acpi_ut_remove_allocation ( 778 u32 list_id, 779 struct acpi_debug_mem_block *allocation, 780 u32 component, 781 char *module, 782 u32 line) 783{ 784 struct acpi_memory_list *mem_list; 785 acpi_status status; 786 787 788 ACPI_FUNCTION_TRACE ("ut_remove_allocation"); 789 790 791 if (list_id > ACPI_MEM_LIST_MAX) { 792 return_ACPI_STATUS (AE_BAD_PARAMETER); 793 } 794 795 mem_list = &acpi_gbl_memory_lists[list_id]; 796 if (NULL == mem_list->list_head) { 797 /* No allocations! */ 798 799 _ACPI_REPORT_ERROR (module, line, component, 800 ("ut_remove_allocation: Empty allocation list, nothing to free!\n")); 801 802 return_ACPI_STATUS (AE_OK); 803 } 804 805 status = acpi_ut_acquire_mutex (ACPI_MTX_MEMORY); 806 if (ACPI_FAILURE (status)) { 807 return_ACPI_STATUS (status); 808 } 809 810 /* Unlink */ 811 812 if (allocation->previous) { 813 (allocation->previous)->next = allocation->next; 814 } 815 else { 816 mem_list->list_head = allocation->next; 817 } 818 819 if (allocation->next) { 820 (allocation->next)->previous = allocation->previous; 821 } 822 823 /* Mark the segment as deleted */ 824 825 ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size); 826 827 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size)); 828 829 status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); 830 return_ACPI_STATUS (status); 831} 832 833 834/******************************************************************************* 835 * 836 * FUNCTION: acpi_ut_dump_allocation_info 837 * 838 * PARAMETERS: 839 * 840 * RETURN: None 841 * 842 * DESCRIPTION: Print some info about the outstanding allocations. 843 * 844 ******************************************************************************/ 845#ifdef ACPI_FUTURE_USAGE 846void 847acpi_ut_dump_allocation_info ( 848 void) 849{ 850/* 851 struct acpi_memory_list *mem_list; 852*/ 853 854 ACPI_FUNCTION_TRACE ("ut_dump_allocation_info"); 855 856/* 857 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 858 ("%30s: %4d (%3d Kb)\n", "Current allocations", 859 mem_list->current_count, 860 ROUND_UP_TO_1K (mem_list->current_size))); 861 862 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 863 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 864 mem_list->max_concurrent_count, 865 ROUND_UP_TO_1K (mem_list->max_concurrent_size))); 866 867 868 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 869 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 870 running_object_count, 871 ROUND_UP_TO_1K (running_object_size))); 872 873 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 874 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 875 running_alloc_count, 876 ROUND_UP_TO_1K (running_alloc_size))); 877 878 879 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 880 ("%30s: %4d (%3d Kb)\n", "Current Nodes", 881 acpi_gbl_current_node_count, 882 ROUND_UP_TO_1K (acpi_gbl_current_node_size))); 883 884 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 885 ("%30s: %4d (%3d Kb)\n", "Max Nodes", 886 acpi_gbl_max_concurrent_node_count, 887 ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node))))); 888*/ 889 return_VOID; 890} 891#endif /* ACPI_FUTURE_USAGE */ 892 893 894/******************************************************************************* 895 * 896 * FUNCTION: acpi_ut_dump_allocations 897 * 898 * PARAMETERS: Component - Component(s) to dump info for. 899 * Module - Module to dump info for. NULL means all. 900 * 901 * RETURN: None 902 * 903 * DESCRIPTION: Print a list of all outstanding allocations. 904 * 905 ******************************************************************************/ 906 907void 908acpi_ut_dump_allocations ( 909 u32 component, 910 char *module) 911{ 912 struct acpi_debug_mem_block *element; 913 union acpi_descriptor *descriptor; 914 u32 num_outstanding = 0; 915 916 917 ACPI_FUNCTION_TRACE ("ut_dump_allocations"); 918 919 920 /* 921 * Walk the allocation list. 922 */ 923 if (ACPI_FAILURE (acpi_ut_acquire_mutex (ACPI_MTX_MEMORY))) { 924 return; 925 } 926 927 element = acpi_gbl_memory_lists[0].list_head; 928 while (element) { 929 if ((element->component & component) && 930 ((module == NULL) || (0 == ACPI_STRCMP (module, element->module)))) { 931 /* Ignore allocated objects that are in a cache */ 932 933 descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space); 934 if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) { 935 acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ", 936 descriptor, element->size, element->module, 937 element->line, acpi_ut_get_descriptor_name (descriptor)); 938 939 /* Most of the elements will be Operand objects. */ 940 941 switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) { 942 case ACPI_DESC_TYPE_OPERAND: 943 acpi_os_printf ("%12.12s R%hd", 944 acpi_ut_get_type_name (descriptor->object.common.type), 945 descriptor->object.common.reference_count); 946 break; 947 948 case ACPI_DESC_TYPE_PARSER: 949 acpi_os_printf ("aml_opcode %04hX", 950 descriptor->op.asl.aml_opcode); 951 break; 952 953 case ACPI_DESC_TYPE_NAMED: 954 acpi_os_printf ("%4.4s", 955 acpi_ut_get_node_name (&descriptor->node)); 956 break; 957 958 default: 959 break; 960 } 961 962 acpi_os_printf ( "\n"); 963 num_outstanding++; 964 } 965 } 966 element = element->next; 967 } 968 969 (void) acpi_ut_release_mutex (ACPI_MTX_MEMORY); 970 971 /* Print summary */ 972 973 if (!num_outstanding) { 974 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 975 "No outstanding allocations.\n")); 976 } 977 else { 978 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 979 "%d(%X) Outstanding allocations\n", 980 num_outstanding, num_outstanding)); 981 } 982 983 return_VOID; 984} 985 986 987#endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */ 988