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