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 
65 void
acpi_ut_release_to_cache(u32 list_id,void * object)66 acpi_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 
121 void *
acpi_ut_acquire_from_cache(u32 list_id)122 acpi_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 
193 void
acpi_ut_delete_generic_cache(u32 list_id)194 acpi_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 
229 acpi_status
acpi_ut_validate_buffer(struct acpi_buffer * buffer)230 acpi_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 
272 acpi_status
acpi_ut_initialize_buffer(struct acpi_buffer * buffer,acpi_size required_length)273 acpi_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 
349 void *
acpi_ut_allocate(acpi_size size,u32 component,char * module,u32 line)350 acpi_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 
399 void *
acpi_ut_callocate(acpi_size size,u32 component,char * module,u32 line)400 acpi_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 
464 void *
acpi_ut_allocate_and_track(acpi_size size,u32 component,char * module,u32 line)465 acpi_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 
510 void *
acpi_ut_callocate_and_track(acpi_size size,u32 component,char * module,u32 line)511 acpi_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 
560 void
acpi_ut_free_and_track(void * allocation,u32 component,char * module,u32 line)561 acpi_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 
614 struct acpi_debug_mem_block *
acpi_ut_find_allocation(u32 list_id,void * allocation)615 acpi_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 
662 acpi_status
acpi_ut_track_allocation(u32 list_id,struct acpi_debug_mem_block * allocation,acpi_size size,u8 alloc_type,u32 component,char * module,u32 line)663 acpi_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 
726 unlock_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 
747 acpi_status
acpi_ut_remove_allocation(u32 list_id,struct acpi_debug_mem_block * allocation,u32 component,char * module,u32 line)748 acpi_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 
817 void
acpi_ut_dump_allocation_info(void)818 acpi_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 
877 void
acpi_ut_dump_allocations(u32 component,char * module)878 acpi_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