ACPICA: Remove extra spaces after periods within comments
[deliverable/linux.git] / drivers / acpi / acpica / uttrack.c
CommitLineData
6d33b6be
LZ
1/******************************************************************************
2 *
3 * Module Name: uttrack - Memory allocation tracking routines (debug only)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2012, Intel Corp.
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 * These procedures are used for tracking memory leaks in the subsystem, and
46 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
47 *
73a3090a 48 * Each memory allocation is tracked via a doubly linked list. Each
6d33b6be 49 * element contains the caller's component, module name, function name, and
73a3090a 50 * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call
6d33b6be
LZ
51 * acpi_ut_track_allocation to add an element to the list; deletion
52 * occurs in the body of acpi_ut_free.
53 */
54
55#include <acpi/acpi.h>
56#include "accommon.h"
57
58#ifdef ACPI_DBG_TRACK_ALLOCATIONS
59
60#define _COMPONENT ACPI_UTILITIES
61ACPI_MODULE_NAME("uttrack")
62
63/* Local prototypes */
64static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation);
65
66static acpi_status
67acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
68 acpi_size size,
69 u8 alloc_type,
70 u32 component, const char *module, u32 line);
71
72static acpi_status
73acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
74 u32 component, const char *module, u32 line);
75
76/*******************************************************************************
77 *
78 * FUNCTION: acpi_ut_create_list
79 *
80 * PARAMETERS: cache_name - Ascii name for the cache
81 * object_size - Size of each cached object
82 * return_cache - Where the new cache object is returned
83 *
84 * RETURN: Status
85 *
86 * DESCRIPTION: Create a local memory list for tracking purposed
87 *
88 ******************************************************************************/
89
90acpi_status
91acpi_ut_create_list(char *list_name,
92 u16 object_size, struct acpi_memory_list **return_cache)
93{
94 struct acpi_memory_list *cache;
95
96 cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
97 if (!cache) {
98 return (AE_NO_MEMORY);
99 }
100
101 ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
102
103 cache->list_name = list_name;
104 cache->object_size = object_size;
105
106 *return_cache = cache;
107 return (AE_OK);
108}
109
110/*******************************************************************************
111 *
112 * FUNCTION: acpi_ut_allocate_and_track
113 *
114 * PARAMETERS: size - Size of the allocation
115 * component - Component type of caller
116 * module - Source file name of caller
117 * line - Line number of caller
118 *
119 * RETURN: Address of the allocated memory on success, NULL on failure.
120 *
121 * DESCRIPTION: The subsystem's equivalent of malloc.
122 *
123 ******************************************************************************/
124
125void *acpi_ut_allocate_and_track(acpi_size size,
126 u32 component, const char *module, u32 line)
127{
128 struct acpi_debug_mem_block *allocation;
129 acpi_status status;
130
131 allocation =
132 acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header),
133 component, module, line);
134 if (!allocation) {
135 return (NULL);
136 }
137
138 status = acpi_ut_track_allocation(allocation, size,
139 ACPI_MEM_MALLOC, component, module,
140 line);
141 if (ACPI_FAILURE(status)) {
142 acpi_os_free(allocation);
143 return (NULL);
144 }
145
146 acpi_gbl_global_list->total_allocated++;
147 acpi_gbl_global_list->total_size += (u32)size;
148 acpi_gbl_global_list->current_total_size += (u32)size;
149 if (acpi_gbl_global_list->current_total_size >
150 acpi_gbl_global_list->max_occupied) {
151 acpi_gbl_global_list->max_occupied =
152 acpi_gbl_global_list->current_total_size;
153 }
154
155 return ((void *)&allocation->user_space);
156}
157
158/*******************************************************************************
159 *
160 * FUNCTION: acpi_ut_allocate_zeroed_and_track
161 *
162 * PARAMETERS: size - Size of the allocation
163 * component - Component type of caller
164 * module - Source file name of caller
165 * line - Line number of caller
166 *
167 * RETURN: Address of the allocated memory on success, NULL on failure.
168 *
169 * DESCRIPTION: Subsystem equivalent of calloc.
170 *
171 ******************************************************************************/
172
173void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
174 u32 component,
175 const char *module, u32 line)
176{
177 struct acpi_debug_mem_block *allocation;
178 acpi_status status;
179
180 allocation =
181 acpi_ut_allocate_zeroed(size + sizeof(struct acpi_debug_mem_header),
182 component, module, line);
183 if (!allocation) {
184
185 /* Report allocation error */
186
187 ACPI_ERROR((module, line,
188 "Could not allocate size %u", (u32)size));
189 return (NULL);
190 }
191
192 status = acpi_ut_track_allocation(allocation, size,
193 ACPI_MEM_CALLOC, component, module,
194 line);
195 if (ACPI_FAILURE(status)) {
196 acpi_os_free(allocation);
197 return (NULL);
198 }
199
200 acpi_gbl_global_list->total_allocated++;
201 acpi_gbl_global_list->total_size += (u32)size;
202 acpi_gbl_global_list->current_total_size += (u32)size;
203 if (acpi_gbl_global_list->current_total_size >
204 acpi_gbl_global_list->max_occupied) {
205 acpi_gbl_global_list->max_occupied =
206 acpi_gbl_global_list->current_total_size;
207 }
208
209 return ((void *)&allocation->user_space);
210}
211
212/*******************************************************************************
213 *
214 * FUNCTION: acpi_ut_free_and_track
215 *
216 * PARAMETERS: allocation - Address of the memory to deallocate
217 * component - Component type of caller
218 * module - Source file name of caller
219 * line - Line number of caller
220 *
221 * RETURN: None
222 *
223 * DESCRIPTION: Frees the memory at Allocation
224 *
225 ******************************************************************************/
226
227void
228acpi_ut_free_and_track(void *allocation,
229 u32 component, const char *module, u32 line)
230{
231 struct acpi_debug_mem_block *debug_block;
232 acpi_status status;
233
234 ACPI_FUNCTION_TRACE_PTR(ut_free, allocation);
235
236 if (NULL == allocation) {
237 ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
238
239 return_VOID;
240 }
241
242 debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
243 (((char *)allocation) -
244 sizeof(struct acpi_debug_mem_header)));
245
246 acpi_gbl_global_list->total_freed++;
247 acpi_gbl_global_list->current_total_size -= debug_block->size;
248
249 status = acpi_ut_remove_allocation(debug_block,
250 component, module, line);
251 if (ACPI_FAILURE(status)) {
252 ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
253 }
254
255 acpi_os_free(debug_block);
256 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
257 return_VOID;
258}
259
260/*******************************************************************************
261 *
262 * FUNCTION: acpi_ut_find_allocation
263 *
264 * PARAMETERS: allocation - Address of allocated memory
265 *
266 * RETURN: A list element if found; NULL otherwise.
267 *
268 * DESCRIPTION: Searches for an element in the global allocation tracking list.
269 *
270 ******************************************************************************/
271
272static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation)
273{
274 struct acpi_debug_mem_block *element;
275
276 ACPI_FUNCTION_ENTRY();
277
278 element = acpi_gbl_global_list->list_head;
279
280 /* Search for the address. */
281
282 while (element) {
283 if (element == allocation) {
284 return (element);
285 }
286
287 element = element->next;
288 }
289
290 return (NULL);
291}
292
293/*******************************************************************************
294 *
295 * FUNCTION: acpi_ut_track_allocation
296 *
297 * PARAMETERS: allocation - Address of allocated memory
298 * size - Size of the allocation
299 * alloc_type - MEM_MALLOC or MEM_CALLOC
300 * component - Component type of caller
301 * module - Source file name of caller
302 * line - Line number of caller
303 *
304 * RETURN: None.
305 *
306 * DESCRIPTION: Inserts an element into the global allocation tracking list.
307 *
308 ******************************************************************************/
309
310static acpi_status
311acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
312 acpi_size size,
313 u8 alloc_type,
314 u32 component, const char *module, u32 line)
315{
316 struct acpi_memory_list *mem_list;
317 struct acpi_debug_mem_block *element;
318 acpi_status status = AE_OK;
319
320 ACPI_FUNCTION_TRACE_PTR(ut_track_allocation, allocation);
321
322 if (acpi_gbl_disable_mem_tracking) {
323 return_ACPI_STATUS(AE_OK);
324 }
325
326 mem_list = acpi_gbl_global_list;
327 status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
328 if (ACPI_FAILURE(status)) {
329 return_ACPI_STATUS(status);
330 }
331
332 /*
333 * Search list for this address to make sure it is not already on the list.
334 * This will catch several kinds of problems.
335 */
336 element = acpi_ut_find_allocation(allocation);
337 if (element) {
338 ACPI_ERROR((AE_INFO,
339 "UtTrackAllocation: Allocation already present in list! (%p)",
340 allocation));
341
342 ACPI_ERROR((AE_INFO, "Element %p Address %p",
343 element, allocation));
344
345 goto unlock_and_exit;
346 }
347
348 /* Fill in the instance data. */
349
350 allocation->size = (u32)size;
351 allocation->alloc_type = alloc_type;
352 allocation->component = component;
353 allocation->line = line;
354
355 ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME);
356 allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
357
358 /* Insert at list head */
359
360 if (mem_list->list_head) {
361 ((struct acpi_debug_mem_block *)(mem_list->list_head))->
362 previous = allocation;
363 }
364
365 allocation->next = mem_list->list_head;
366 allocation->previous = NULL;
367
368 mem_list->list_head = allocation;
369
370 unlock_and_exit:
371 status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
372 return_ACPI_STATUS(status);
373}
374
375/*******************************************************************************
376 *
377 * FUNCTION: acpi_ut_remove_allocation
378 *
379 * PARAMETERS: allocation - Address of allocated memory
380 * component - Component type of caller
381 * module - Source file name of caller
382 * line - Line number of caller
383 *
384 * RETURN:
385 *
386 * DESCRIPTION: Deletes an element from the global allocation tracking list.
387 *
388 ******************************************************************************/
389
390static acpi_status
391acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
392 u32 component, const char *module, u32 line)
393{
394 struct acpi_memory_list *mem_list;
395 acpi_status status;
396
397 ACPI_FUNCTION_TRACE(ut_remove_allocation);
398
399 if (acpi_gbl_disable_mem_tracking) {
400 return_ACPI_STATUS(AE_OK);
401 }
402
403 mem_list = acpi_gbl_global_list;
404 if (NULL == mem_list->list_head) {
405
406 /* No allocations! */
407
408 ACPI_ERROR((module, line,
409 "Empty allocation list, nothing to free!"));
410
411 return_ACPI_STATUS(AE_OK);
412 }
413
414 status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
415 if (ACPI_FAILURE(status)) {
416 return_ACPI_STATUS(status);
417 }
418
419 /* Unlink */
420
421 if (allocation->previous) {
422 (allocation->previous)->next = allocation->next;
423 } else {
424 mem_list->list_head = allocation->next;
425 }
426
427 if (allocation->next) {
428 (allocation->next)->previous = allocation->previous;
429 }
430
431 /* Mark the segment as deleted */
432
433 ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size);
434
435 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
436 allocation->size));
437
438 status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
439 return_ACPI_STATUS(status);
440}
441
442/*******************************************************************************
443 *
444 * FUNCTION: acpi_ut_dump_allocation_info
445 *
446 * PARAMETERS:
447 *
448 * RETURN: None
449 *
450 * DESCRIPTION: Print some info about the outstanding allocations.
451 *
452 ******************************************************************************/
453
454void acpi_ut_dump_allocation_info(void)
455{
456/*
457 struct acpi_memory_list *mem_list;
458*/
459
460 ACPI_FUNCTION_TRACE(ut_dump_allocation_info);
461
462/*
463 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
464 ("%30s: %4d (%3d Kb)\n", "Current allocations",
465 mem_list->current_count,
466 ROUND_UP_TO_1K (mem_list->current_size)));
467
468 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
469 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
470 mem_list->max_concurrent_count,
471 ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
472
473 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
474 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
475 running_object_count,
476 ROUND_UP_TO_1K (running_object_size)));
477
478 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
479 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
480 running_alloc_count,
481 ROUND_UP_TO_1K (running_alloc_size)));
482
483 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
484 ("%30s: %4d (%3d Kb)\n", "Current Nodes",
485 acpi_gbl_current_node_count,
486 ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
487
488 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
489 ("%30s: %4d (%3d Kb)\n", "Max Nodes",
490 acpi_gbl_max_concurrent_node_count,
491 ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
492 sizeof (struct acpi_namespace_node)))));
493*/
494 return_VOID;
495}
496
497/*******************************************************************************
498 *
499 * FUNCTION: acpi_ut_dump_allocations
500 *
501 * PARAMETERS: component - Component(s) to dump info for.
73a3090a 502 * module - Module to dump info for. NULL means all.
6d33b6be
LZ
503 *
504 * RETURN: None
505 *
506 * DESCRIPTION: Print a list of all outstanding allocations.
507 *
508 ******************************************************************************/
509
510void acpi_ut_dump_allocations(u32 component, const char *module)
511{
512 struct acpi_debug_mem_block *element;
513 union acpi_descriptor *descriptor;
514 u32 num_outstanding = 0;
515 u8 descriptor_type;
516
517 ACPI_FUNCTION_TRACE(ut_dump_allocations);
518
519 if (acpi_gbl_disable_mem_tracking) {
68aafc35 520 return_VOID;
6d33b6be
LZ
521 }
522
523 /*
524 * Walk the allocation list.
525 */
526 if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
68aafc35 527 return_VOID;
6d33b6be
LZ
528 }
529
530 element = acpi_gbl_global_list->list_head;
531 while (element) {
532 if ((element->component & component) &&
533 ((module == NULL)
534 || (0 == ACPI_STRCMP(module, element->module)))) {
535 descriptor =
536 ACPI_CAST_PTR(union acpi_descriptor,
537 &element->user_space);
538
539 if (element->size <
540 sizeof(struct acpi_common_descriptor)) {
541 acpi_os_printf("%p Length 0x%04X %9.9s-%u "
542 "[Not a Descriptor - too small]\n",
543 descriptor, element->size,
544 element->module, element->line);
545 } else {
546 /* Ignore allocated objects that are in a cache */
547
548 if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
549 ACPI_DESC_TYPE_CACHED) {
550 acpi_os_printf
551 ("%p Length 0x%04X %9.9s-%u [%s] ",
552 descriptor, element->size,
553 element->module, element->line,
554 acpi_ut_get_descriptor_name
555 (descriptor));
556
557 /* Validate the descriptor type using Type field and length */
558
559 descriptor_type = 0; /* Not a valid descriptor type */
560
561 switch (ACPI_GET_DESCRIPTOR_TYPE
562 (descriptor)) {
563 case ACPI_DESC_TYPE_OPERAND:
564 if (element->size ==
565 sizeof(union
566 acpi_operand_object))
567 {
568 descriptor_type =
569 ACPI_DESC_TYPE_OPERAND;
570 }
571 break;
572
573 case ACPI_DESC_TYPE_PARSER:
574 if (element->size ==
575 sizeof(union
576 acpi_parse_object)) {
577 descriptor_type =
578 ACPI_DESC_TYPE_PARSER;
579 }
580 break;
581
582 case ACPI_DESC_TYPE_NAMED:
583 if (element->size ==
584 sizeof(struct
585 acpi_namespace_node))
586 {
587 descriptor_type =
588 ACPI_DESC_TYPE_NAMED;
589 }
590 break;
591
592 default:
593 break;
594 }
595
596 /* Display additional info for the major descriptor types */
597
598 switch (descriptor_type) {
599 case ACPI_DESC_TYPE_OPERAND:
600 acpi_os_printf
601 ("%12.12s RefCount 0x%04X\n",
602 acpi_ut_get_type_name
603 (descriptor->object.common.
604 type),
605 descriptor->object.common.
606 reference_count);
607 break;
608
609 case ACPI_DESC_TYPE_PARSER:
610 acpi_os_printf
611 ("AmlOpcode 0x%04hX\n",
612 descriptor->op.asl.
613 aml_opcode);
614 break;
615
616 case ACPI_DESC_TYPE_NAMED:
617 acpi_os_printf("%4.4s\n",
618 acpi_ut_get_node_name
619 (&descriptor->
620 node));
621 break;
622
623 default:
624 acpi_os_printf("\n");
625 break;
626 }
627 }
628 }
629
630 num_outstanding++;
631 }
632
633 element = element->next;
634 }
635
636 (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
637
638 /* Print summary */
639
640 if (!num_outstanding) {
641 ACPI_INFO((AE_INFO, "No outstanding allocations"));
642 } else {
643 ACPI_ERROR((AE_INFO, "%u(0x%X) Outstanding allocations",
644 num_outstanding, num_outstanding));
645 }
646
647 return_VOID;
648}
649
650#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
This page took 0.048764 seconds and 5 git commands to generate.