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