1/****************************************************************************** 2 * 3 * Module Name: uttrack - Memory allocation tracking routines (debug only) 4 * 5 *****************************************************************************/ 6 7/****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2016, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116/* 117 * These procedures are used for tracking memory leaks in the subsystem, and 118 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. 119 * 120 * Each memory allocation is tracked via a doubly linked list. Each 121 * element contains the caller's component, module name, function name, and 122 * line number. AcpiUtAllocate and AcpiUtAllocateZeroed call 123 * AcpiUtTrackAllocation to add an element to the list; deletion 124 * occurs in the body of AcpiUtFree. 125 */ 126 127#include "acpi.h" 128#include "accommon.h" 129 130#ifdef ACPI_DBG_TRACK_ALLOCATIONS 131 132#define _COMPONENT ACPI_UTILITIES 133 ACPI_MODULE_NAME ("uttrack") 134 135 136/* Local prototypes */ 137 138static ACPI_DEBUG_MEM_BLOCK * 139AcpiUtFindAllocation ( 140 ACPI_DEBUG_MEM_BLOCK *Allocation); 141 142static ACPI_STATUS 143AcpiUtTrackAllocation ( 144 ACPI_DEBUG_MEM_BLOCK *Address, 145 ACPI_SIZE Size, 146 UINT8 AllocType, 147 UINT32 Component, 148 const char *Module, 149 UINT32 Line); 150 151static ACPI_STATUS 152AcpiUtRemoveAllocation ( 153 ACPI_DEBUG_MEM_BLOCK *Address, 154 UINT32 Component, 155 const char *Module, 156 UINT32 Line); 157 158 159/******************************************************************************* 160 * 161 * FUNCTION: AcpiUtCreateList 162 * 163 * PARAMETERS: CacheName - Ascii name for the cache 164 * ObjectSize - Size of each cached object 165 * ReturnCache - Where the new cache object is returned 166 * 167 * RETURN: Status 168 * 169 * DESCRIPTION: Create a local memory list for tracking purposed 170 * 171 ******************************************************************************/ 172 173ACPI_STATUS 174AcpiUtCreateList ( 175 const char *ListName, 176 UINT16 ObjectSize, 177 ACPI_MEMORY_LIST **ReturnCache) 178{ 179 ACPI_MEMORY_LIST *Cache; 180 181 182 Cache = AcpiOsAllocateZeroed (sizeof (ACPI_MEMORY_LIST)); 183 if (!Cache) 184 { 185 return (AE_NO_MEMORY); 186 } 187 188 Cache->ListName = ListName; 189 Cache->ObjectSize = ObjectSize; 190 191 *ReturnCache = Cache; 192 return (AE_OK); 193} 194 195 196/******************************************************************************* 197 * 198 * FUNCTION: AcpiUtAllocateAndTrack 199 * 200 * PARAMETERS: Size - Size of the allocation 201 * Component - Component type of caller 202 * Module - Source file name of caller 203 * Line - Line number of caller 204 * 205 * RETURN: Address of the allocated memory on success, NULL on failure. 206 * 207 * DESCRIPTION: The subsystem's equivalent of malloc. 208 * 209 ******************************************************************************/ 210 211void * 212AcpiUtAllocateAndTrack ( 213 ACPI_SIZE Size, 214 UINT32 Component, 215 const char *Module, 216 UINT32 Line) 217{ 218 ACPI_DEBUG_MEM_BLOCK *Allocation; 219 ACPI_STATUS Status; 220 221 222 /* Check for an inadvertent size of zero bytes */ 223 224 if (!Size) 225 { 226 ACPI_WARNING ((Module, Line, 227 "Attempt to allocate zero bytes, allocating 1 byte")); 228 Size = 1; 229 } 230 231 Allocation = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER)); 232 if (!Allocation) 233 { 234 /* Report allocation error */ 235 236 ACPI_WARNING ((Module, Line, 237 "Could not allocate size %u", (UINT32) Size)); 238 239 return (NULL); 240 } 241 242 Status = AcpiUtTrackAllocation ( 243 Allocation, Size, ACPI_MEM_MALLOC, Component, Module, Line); 244 if (ACPI_FAILURE (Status)) 245 { 246 AcpiOsFree (Allocation); 247 return (NULL); 248 } 249 250 AcpiGbl_GlobalList->TotalAllocated++; 251 AcpiGbl_GlobalList->TotalSize += (UINT32) Size; 252 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; 253 254 if (AcpiGbl_GlobalList->CurrentTotalSize > 255 AcpiGbl_GlobalList->MaxOccupied) 256 { 257 AcpiGbl_GlobalList->MaxOccupied = 258 AcpiGbl_GlobalList->CurrentTotalSize; 259 } 260 261 return ((void *) &Allocation->UserSpace); 262} 263 264 265/******************************************************************************* 266 * 267 * FUNCTION: AcpiUtAllocateZeroedAndTrack 268 * 269 * PARAMETERS: Size - Size of the allocation 270 * Component - Component type of caller 271 * Module - Source file name of caller 272 * Line - Line number of caller 273 * 274 * RETURN: Address of the allocated memory on success, NULL on failure. 275 * 276 * DESCRIPTION: Subsystem equivalent of calloc. 277 * 278 ******************************************************************************/ 279 280void * 281AcpiUtAllocateZeroedAndTrack ( 282 ACPI_SIZE Size, 283 UINT32 Component, 284 const char *Module, 285 UINT32 Line) 286{ 287 ACPI_DEBUG_MEM_BLOCK *Allocation; 288 ACPI_STATUS Status; 289 290 291 /* Check for an inadvertent size of zero bytes */ 292 293 if (!Size) 294 { 295 ACPI_WARNING ((Module, Line, 296 "Attempt to allocate zero bytes, allocating 1 byte")); 297 Size = 1; 298 } 299 300 Allocation = AcpiOsAllocateZeroed ( 301 Size + sizeof (ACPI_DEBUG_MEM_HEADER)); 302 if (!Allocation) 303 { 304 /* Report allocation error */ 305 306 ACPI_ERROR ((Module, Line, 307 "Could not allocate size %u", (UINT32) Size)); 308 return (NULL); 309 } 310 311 Status = AcpiUtTrackAllocation (Allocation, Size, 312 ACPI_MEM_CALLOC, Component, Module, Line); 313 if (ACPI_FAILURE (Status)) 314 { 315 AcpiOsFree (Allocation); 316 return (NULL); 317 } 318 319 AcpiGbl_GlobalList->TotalAllocated++; 320 AcpiGbl_GlobalList->TotalSize += (UINT32) Size; 321 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size; 322 323 if (AcpiGbl_GlobalList->CurrentTotalSize > 324 AcpiGbl_GlobalList->MaxOccupied) 325 { 326 AcpiGbl_GlobalList->MaxOccupied = 327 AcpiGbl_GlobalList->CurrentTotalSize; 328 } 329 330 return ((void *) &Allocation->UserSpace); 331} 332 333 334/******************************************************************************* 335 * 336 * FUNCTION: AcpiUtFreeAndTrack 337 * 338 * PARAMETERS: Allocation - Address of the memory to deallocate 339 * Component - Component type of caller 340 * Module - Source file name of caller 341 * Line - Line number of caller 342 * 343 * RETURN: None 344 * 345 * DESCRIPTION: Frees the memory at Allocation 346 * 347 ******************************************************************************/ 348 349void 350AcpiUtFreeAndTrack ( 351 void *Allocation, 352 UINT32 Component, 353 const char *Module, 354 UINT32 Line) 355{ 356 ACPI_DEBUG_MEM_BLOCK *DebugBlock; 357 ACPI_STATUS Status; 358 359 360 ACPI_FUNCTION_TRACE_PTR (UtFree, Allocation); 361 362 363 if (NULL == Allocation) 364 { 365 ACPI_ERROR ((Module, Line, 366 "Attempt to delete a NULL address")); 367 368 return_VOID; 369 } 370 371 DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK, 372 (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER))); 373 374 AcpiGbl_GlobalList->TotalFreed++; 375 AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size; 376 377 Status = AcpiUtRemoveAllocation (DebugBlock, Component, Module, Line); 378 if (ACPI_FAILURE (Status)) 379 { 380 ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory")); 381 } 382 383 AcpiOsFree (DebugBlock); 384 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n", 385 Allocation, DebugBlock)); 386 return_VOID; 387} 388 389 390/******************************************************************************* 391 * 392 * FUNCTION: AcpiUtFindAllocation 393 * 394 * PARAMETERS: Allocation - Address of allocated memory 395 * 396 * RETURN: Three cases: 397 * 1) List is empty, NULL is returned. 398 * 2) Element was found. Returns Allocation parameter. 399 * 3) Element was not found. Returns position where it should be 400 * inserted into the list. 401 * 402 * DESCRIPTION: Searches for an element in the global allocation tracking list. 403 * If the element is not found, returns the location within the 404 * list where the element should be inserted. 405 * 406 * Note: The list is ordered by larger-to-smaller addresses. 407 * 408 * This global list is used to detect memory leaks in ACPICA as 409 * well as other issues such as an attempt to release the same 410 * internal object more than once. Although expensive as far 411 * as cpu time, this list is much more helpful for finding these 412 * types of issues than using memory leak detectors outside of 413 * the ACPICA code. 414 * 415 ******************************************************************************/ 416 417static ACPI_DEBUG_MEM_BLOCK * 418AcpiUtFindAllocation ( 419 ACPI_DEBUG_MEM_BLOCK *Allocation) 420{ 421 ACPI_DEBUG_MEM_BLOCK *Element; 422 423 424 Element = AcpiGbl_GlobalList->ListHead; 425 if (!Element) 426 { 427 return (NULL); 428 } 429 430 /* 431 * Search for the address. 432 * 433 * Note: List is ordered by larger-to-smaller addresses, on the 434 * assumption that a new allocation usually has a larger address 435 * than previous allocations. 436 */ 437 while (Element > Allocation) 438 { 439 /* Check for end-of-list */ 440 441 if (!Element->Next) 442 { 443 return (Element); 444 } 445 446 Element = Element->Next; 447 } 448 449 if (Element == Allocation) 450 { 451 return (Element); 452 } 453 454 return (Element->Previous); 455} 456 457 458/******************************************************************************* 459 * 460 * FUNCTION: AcpiUtTrackAllocation 461 * 462 * PARAMETERS: Allocation - Address of allocated memory 463 * Size - Size of the allocation 464 * AllocType - MEM_MALLOC or MEM_CALLOC 465 * Component - Component type of caller 466 * Module - Source file name of caller 467 * Line - Line number of caller 468 * 469 * RETURN: Status 470 * 471 * DESCRIPTION: Inserts an element into the global allocation tracking list. 472 * 473 ******************************************************************************/ 474 475static ACPI_STATUS 476AcpiUtTrackAllocation ( 477 ACPI_DEBUG_MEM_BLOCK *Allocation, 478 ACPI_SIZE Size, 479 UINT8 AllocType, 480 UINT32 Component, 481 const char *Module, 482 UINT32 Line) 483{ 484 ACPI_MEMORY_LIST *MemList; 485 ACPI_DEBUG_MEM_BLOCK *Element; 486 ACPI_STATUS Status = AE_OK; 487 488 489 ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation); 490 491 492 if (AcpiGbl_DisableMemTracking) 493 { 494 return_ACPI_STATUS (AE_OK); 495 } 496 497 MemList = AcpiGbl_GlobalList; 498 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 499 if (ACPI_FAILURE (Status)) 500 { 501 return_ACPI_STATUS (Status); 502 } 503 504 /* 505 * Search the global list for this address to make sure it is not 506 * already present. This will catch several kinds of problems. 507 */ 508 Element = AcpiUtFindAllocation (Allocation); 509 if (Element == Allocation) 510 { 511 ACPI_ERROR ((AE_INFO, 512 "UtTrackAllocation: Allocation (%p) already present in global list!", 513 Allocation)); 514 goto UnlockAndExit; 515 } 516 517 /* Fill in the instance data */ 518 519 Allocation->Size = (UINT32) Size; 520 Allocation->AllocType = AllocType; 521 Allocation->Component = Component; 522 Allocation->Line = Line; 523 524 strncpy (Allocation->Module, Module, ACPI_MAX_MODULE_NAME); 525 Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0; 526 527 if (!Element) 528 { 529 /* Insert at list head */ 530 531 if (MemList->ListHead) 532 { 533 ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous = 534 Allocation; 535 } 536 537 Allocation->Next = MemList->ListHead; 538 Allocation->Previous = NULL; 539 540 MemList->ListHead = Allocation; 541 } 542 else 543 { 544 /* Insert after element */ 545 546 Allocation->Next = Element->Next; 547 Allocation->Previous = Element; 548 549 if (Element->Next) 550 { 551 (Element->Next)->Previous = Allocation; 552 } 553 554 Element->Next = Allocation; 555 } 556 557 558UnlockAndExit: 559 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 560 return_ACPI_STATUS (Status); 561} 562 563 564/******************************************************************************* 565 * 566 * FUNCTION: AcpiUtRemoveAllocation 567 * 568 * PARAMETERS: Allocation - Address of allocated memory 569 * Component - Component type of caller 570 * Module - Source file name of caller 571 * Line - Line number of caller 572 * 573 * RETURN: Status 574 * 575 * DESCRIPTION: Deletes an element from the global allocation tracking list. 576 * 577 ******************************************************************************/ 578 579static ACPI_STATUS 580AcpiUtRemoveAllocation ( 581 ACPI_DEBUG_MEM_BLOCK *Allocation, 582 UINT32 Component, 583 const char *Module, 584 UINT32 Line) 585{ 586 ACPI_MEMORY_LIST *MemList; 587 ACPI_STATUS Status; 588 589 590 ACPI_FUNCTION_NAME (UtRemoveAllocation); 591 592 593 if (AcpiGbl_DisableMemTracking) 594 { 595 return (AE_OK); 596 } 597 598 MemList = AcpiGbl_GlobalList; 599 if (NULL == MemList->ListHead) 600 { 601 /* No allocations! */ 602 603 ACPI_ERROR ((Module, Line, 604 "Empty allocation list, nothing to free!")); 605 606 return (AE_OK); 607 } 608 609 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY); 610 if (ACPI_FAILURE (Status)) 611 { 612 return (Status); 613 } 614 615 /* Unlink */ 616 617 if (Allocation->Previous) 618 { 619 (Allocation->Previous)->Next = Allocation->Next; 620 } 621 else 622 { 623 MemList->ListHead = Allocation->Next; 624 } 625 626 if (Allocation->Next) 627 { 628 (Allocation->Next)->Previous = Allocation->Previous; 629 } 630 631 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n", 632 &Allocation->UserSpace, Allocation->Size)); 633 634 /* Mark the segment as deleted */ 635 636 memset (&Allocation->UserSpace, 0xEA, Allocation->Size); 637 638 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 639 return (Status); 640} 641 642 643/******************************************************************************* 644 * 645 * FUNCTION: AcpiUtDumpAllocationInfo 646 * 647 * PARAMETERS: None 648 * 649 * RETURN: None 650 * 651 * DESCRIPTION: Print some info about the outstanding allocations. 652 * 653 ******************************************************************************/ 654 655void 656AcpiUtDumpAllocationInfo ( 657 void) 658{ 659/* 660 ACPI_MEMORY_LIST *MemList; 661*/ 662 663 ACPI_FUNCTION_TRACE (UtDumpAllocationInfo); 664 665/* 666 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 667 ("%30s: %4d (%3d Kb)\n", "Current allocations", 668 MemList->CurrentCount, 669 ROUND_UP_TO_1K (MemList->CurrentSize))); 670 671 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 672 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", 673 MemList->MaxConcurrentCount, 674 ROUND_UP_TO_1K (MemList->MaxConcurrentSize))); 675 676 677 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 678 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", 679 RunningObjectCount, 680 ROUND_UP_TO_1K (RunningObjectSize))); 681 682 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 683 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", 684 RunningAllocCount, 685 ROUND_UP_TO_1K (RunningAllocSize))); 686 687 688 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 689 ("%30s: %4d (%3d Kb)\n", "Current Nodes", 690 AcpiGbl_CurrentNodeCount, 691 ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize))); 692 693 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, 694 ("%30s: %4d (%3d Kb)\n", "Max Nodes", 695 AcpiGbl_MaxConcurrentNodeCount, 696 ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount * 697 sizeof (ACPI_NAMESPACE_NODE))))); 698*/ 699 return_VOID; 700} 701 702 703/******************************************************************************* 704 * 705 * FUNCTION: AcpiUtDumpAllocations 706 * 707 * PARAMETERS: Component - Component(s) to dump info for. 708 * Module - Module to dump info for. NULL means all. 709 * 710 * RETURN: None 711 * 712 * DESCRIPTION: Print a list of all outstanding allocations. 713 * 714 ******************************************************************************/ 715 716void 717AcpiUtDumpAllocations ( 718 UINT32 Component, 719 const char *Module) 720{ 721 ACPI_DEBUG_MEM_BLOCK *Element; 722 ACPI_DESCRIPTOR *Descriptor; 723 UINT32 NumOutstanding = 0; 724 UINT8 DescriptorType; 725 726 727 ACPI_FUNCTION_TRACE (UtDumpAllocations); 728 729 730 if (AcpiGbl_DisableMemTracking) 731 { 732 return_VOID; 733 } 734 735 /* 736 * Walk the allocation list. 737 */ 738 if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY))) 739 { 740 return_VOID; 741 } 742 743 Element = AcpiGbl_GlobalList->ListHead; 744 while (Element) 745 { 746 if ((Element->Component & Component) && 747 ((Module == NULL) || (0 == strcmp (Module, Element->Module)))) 748 { 749 Descriptor = ACPI_CAST_PTR ( 750 ACPI_DESCRIPTOR, &Element->UserSpace); 751 752 if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR)) 753 { 754 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u " 755 "[Not a Descriptor - too small]\n", 756 Descriptor, Element->Size, Element->Module, 757 Element->Line); 758 } 759 else 760 { 761 /* Ignore allocated objects that are in a cache */ 762 763 if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) != 764 ACPI_DESC_TYPE_CACHED) 765 { 766 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ", 767 Descriptor, Element->Size, Element->Module, 768 Element->Line, AcpiUtGetDescriptorName (Descriptor)); 769 770 /* Validate the descriptor type using Type field and length */ 771 772 DescriptorType = 0; /* Not a valid descriptor type */ 773 774 switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor)) 775 { 776 case ACPI_DESC_TYPE_OPERAND: 777 778 if (Element->Size == sizeof (ACPI_OPERAND_OBJECT)) 779 { 780 DescriptorType = ACPI_DESC_TYPE_OPERAND; 781 } 782 break; 783 784 case ACPI_DESC_TYPE_PARSER: 785 786 if (Element->Size == sizeof (ACPI_PARSE_OBJECT)) 787 { 788 DescriptorType = ACPI_DESC_TYPE_PARSER; 789 } 790 break; 791 792 case ACPI_DESC_TYPE_NAMED: 793 794 if (Element->Size == sizeof (ACPI_NAMESPACE_NODE)) 795 { 796 DescriptorType = ACPI_DESC_TYPE_NAMED; 797 } 798 break; 799 800 default: 801 802 break; 803 } 804 805 /* Display additional info for the major descriptor types */ 806 807 switch (DescriptorType) 808 { 809 case ACPI_DESC_TYPE_OPERAND: 810 811 AcpiOsPrintf ("%12.12s RefCount 0x%04X\n", 812 AcpiUtGetTypeName (Descriptor->Object.Common.Type), 813 Descriptor->Object.Common.ReferenceCount); 814 break; 815 816 case ACPI_DESC_TYPE_PARSER: 817 818 AcpiOsPrintf ("AmlOpcode 0x%04hX\n", 819 Descriptor->Op.Asl.AmlOpcode); 820 break; 821 822 case ACPI_DESC_TYPE_NAMED: 823 824 AcpiOsPrintf ("%4.4s\n", 825 AcpiUtGetNodeName (&Descriptor->Node)); 826 break; 827 828 default: 829 830 AcpiOsPrintf ( "\n"); 831 break; 832 } 833 } 834 } 835 836 NumOutstanding++; 837 } 838 839 Element = Element->Next; 840 } 841 842 (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY); 843 844 /* Print summary */ 845 846 if (!NumOutstanding) 847 { 848 ACPI_INFO (("No outstanding allocations")); 849 } 850 else 851 { 852 ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations", 853 NumOutstanding, NumOutstanding)); 854 } 855 856 return_VOID; 857} 858 859#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ 860