This source file includes following definitions.
- ACPI_MODULE_NAME
- acpi_ut_allocate_and_track
- acpi_ut_allocate_zeroed_and_track
- acpi_ut_free_and_track
- acpi_ut_find_allocation
- acpi_ut_track_allocation
- acpi_ut_remove_allocation
- acpi_ut_dump_allocation_info
- acpi_ut_dump_allocations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <acpi/acpi.h>
22 #include "accommon.h"
23
24 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
25
26 #define _COMPONENT ACPI_UTILITIES
27 ACPI_MODULE_NAME("uttrack")
28
29
30 static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
31 acpi_debug_mem_block
32 *allocation);
33
34 static acpi_status
35 acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
36 acpi_size size,
37 u8 alloc_type,
38 u32 component, const char *module, u32 line);
39
40 static acpi_status
41 acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
42 u32 component, const char *module, u32 line);
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 acpi_status
59 acpi_ut_create_list(const char *list_name,
60 u16 object_size, struct acpi_memory_list **return_cache)
61 {
62 struct acpi_memory_list *cache;
63
64 cache = acpi_os_allocate_zeroed(sizeof(struct acpi_memory_list));
65 if (!cache) {
66 return (AE_NO_MEMORY);
67 }
68
69 cache->list_name = list_name;
70 cache->object_size = object_size;
71
72 *return_cache = cache;
73 return (AE_OK);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 void *acpi_ut_allocate_and_track(acpi_size size,
92 u32 component, const char *module, u32 line)
93 {
94 struct acpi_debug_mem_block *allocation;
95 acpi_status status;
96
97
98
99 if (!size) {
100 ACPI_WARNING((module, line,
101 "Attempt to allocate zero bytes, allocating 1 byte"));
102 size = 1;
103 }
104
105 allocation =
106 acpi_os_allocate(size + sizeof(struct acpi_debug_mem_header));
107 if (!allocation) {
108
109
110
111 ACPI_WARNING((module, line,
112 "Could not allocate size %u", (u32)size));
113
114 return (NULL);
115 }
116
117 status =
118 acpi_ut_track_allocation(allocation, size, ACPI_MEM_MALLOC,
119 component, module, line);
120 if (ACPI_FAILURE(status)) {
121 acpi_os_free(allocation);
122 return (NULL);
123 }
124
125 acpi_gbl_global_list->total_allocated++;
126 acpi_gbl_global_list->total_size += (u32)size;
127 acpi_gbl_global_list->current_total_size += (u32)size;
128
129 if (acpi_gbl_global_list->current_total_size >
130 acpi_gbl_global_list->max_occupied) {
131 acpi_gbl_global_list->max_occupied =
132 acpi_gbl_global_list->current_total_size;
133 }
134
135 return ((void *)&allocation->user_space);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
154 u32 component,
155 const char *module, u32 line)
156 {
157 struct acpi_debug_mem_block *allocation;
158 acpi_status status;
159
160
161
162 if (!size) {
163 ACPI_WARNING((module, line,
164 "Attempt to allocate zero bytes, allocating 1 byte"));
165 size = 1;
166 }
167
168 allocation =
169 acpi_os_allocate_zeroed(size +
170 sizeof(struct acpi_debug_mem_header));
171 if (!allocation) {
172
173
174
175 ACPI_ERROR((module, line,
176 "Could not allocate size %u", (u32)size));
177 return (NULL);
178 }
179
180 status = acpi_ut_track_allocation(allocation, size,
181 ACPI_MEM_CALLOC, component, module,
182 line);
183 if (ACPI_FAILURE(status)) {
184 acpi_os_free(allocation);
185 return (NULL);
186 }
187
188 acpi_gbl_global_list->total_allocated++;
189 acpi_gbl_global_list->total_size += (u32)size;
190 acpi_gbl_global_list->current_total_size += (u32)size;
191
192 if (acpi_gbl_global_list->current_total_size >
193 acpi_gbl_global_list->max_occupied) {
194 acpi_gbl_global_list->max_occupied =
195 acpi_gbl_global_list->current_total_size;
196 }
197
198 return ((void *)&allocation->user_space);
199 }
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 void
217 acpi_ut_free_and_track(void *allocation,
218 u32 component, const char *module, u32 line)
219 {
220 struct acpi_debug_mem_block *debug_block;
221 acpi_status status;
222
223 ACPI_FUNCTION_TRACE_PTR(ut_free, allocation);
224
225 if (NULL == allocation) {
226 ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
227
228 return_VOID;
229 }
230
231 debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
232 (((char *)allocation) -
233 sizeof(struct acpi_debug_mem_header)));
234
235 acpi_gbl_global_list->total_freed++;
236 acpi_gbl_global_list->current_total_size -= debug_block->size;
237
238 status =
239 acpi_ut_remove_allocation(debug_block, component, module, line);
240 if (ACPI_FAILURE(status)) {
241 ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
242 }
243
244 acpi_os_free(debug_block);
245 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n",
246 allocation, debug_block));
247 return_VOID;
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
278 acpi_debug_mem_block
279 *allocation)
280 {
281 struct acpi_debug_mem_block *element;
282
283 element = acpi_gbl_global_list->list_head;
284 if (!element) {
285 return (NULL);
286 }
287
288
289
290
291
292
293
294
295 while (element > allocation) {
296
297
298
299 if (!element->next) {
300 return (element);
301 }
302
303 element = element->next;
304 }
305
306 if (element == allocation) {
307 return (element);
308 }
309
310 return (element->previous);
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 static acpi_status
331 acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
332 acpi_size size,
333 u8 alloc_type,
334 u32 component, const char *module, u32 line)
335 {
336 struct acpi_memory_list *mem_list;
337 struct acpi_debug_mem_block *element;
338 acpi_status status = AE_OK;
339
340 ACPI_FUNCTION_TRACE_PTR(ut_track_allocation, allocation);
341
342 if (acpi_gbl_disable_mem_tracking) {
343 return_ACPI_STATUS(AE_OK);
344 }
345
346 mem_list = acpi_gbl_global_list;
347 status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
348 if (ACPI_FAILURE(status)) {
349 return_ACPI_STATUS(status);
350 }
351
352
353
354
355
356 element = acpi_ut_find_allocation(allocation);
357 if (element == allocation) {
358 ACPI_ERROR((AE_INFO,
359 "UtTrackAllocation: Allocation (%p) already present in global list!",
360 allocation));
361 goto unlock_and_exit;
362 }
363
364
365
366 allocation->size = (u32)size;
367 allocation->alloc_type = alloc_type;
368 allocation->component = component;
369 allocation->line = line;
370
371 acpi_ut_safe_strncpy(allocation->module, (char *)module,
372 ACPI_MAX_MODULE_NAME);
373
374 if (!element) {
375
376
377
378 if (mem_list->list_head) {
379 ((struct acpi_debug_mem_block *)(mem_list->list_head))->
380 previous = allocation;
381 }
382
383 allocation->next = mem_list->list_head;
384 allocation->previous = NULL;
385
386 mem_list->list_head = allocation;
387 } else {
388
389
390 allocation->next = element->next;
391 allocation->previous = element;
392
393 if (element->next) {
394 (element->next)->previous = allocation;
395 }
396
397 element->next = allocation;
398 }
399
400 unlock_and_exit:
401 status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
402 return_ACPI_STATUS(status);
403 }
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420 static acpi_status
421 acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
422 u32 component, const char *module, u32 line)
423 {
424 struct acpi_memory_list *mem_list;
425 acpi_status status;
426
427 ACPI_FUNCTION_NAME(ut_remove_allocation);
428
429 if (acpi_gbl_disable_mem_tracking) {
430 return (AE_OK);
431 }
432
433 mem_list = acpi_gbl_global_list;
434 if (NULL == mem_list->list_head) {
435
436
437
438 ACPI_ERROR((module, line,
439 "Empty allocation list, nothing to free!"));
440
441 return (AE_OK);
442 }
443
444 status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
445 if (ACPI_FAILURE(status)) {
446 return (status);
447 }
448
449
450
451 if (allocation->previous) {
452 (allocation->previous)->next = allocation->next;
453 } else {
454 mem_list->list_head = allocation->next;
455 }
456
457 if (allocation->next) {
458 (allocation->next)->previous = allocation->previous;
459 }
460
461 ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n",
462 &allocation->user_space, allocation->size));
463
464
465
466 memset(&allocation->user_space, 0xEA, allocation->size);
467
468 status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
469 return (status);
470 }
471
472
473
474
475
476
477
478
479
480
481
482
483
484 void acpi_ut_dump_allocation_info(void)
485 {
486
487
488
489
490 ACPI_FUNCTION_TRACE(ut_dump_allocation_info);
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524 return_VOID;
525 }
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540 void acpi_ut_dump_allocations(u32 component, const char *module)
541 {
542 struct acpi_debug_mem_block *element;
543 union acpi_descriptor *descriptor;
544 u32 num_outstanding = 0;
545 u8 descriptor_type;
546
547 ACPI_FUNCTION_TRACE(ut_dump_allocations);
548
549 if (acpi_gbl_disable_mem_tracking) {
550 return_VOID;
551 }
552
553
554
555
556 if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
557 return_VOID;
558 }
559
560 if (!acpi_gbl_global_list) {
561 goto exit;
562 }
563
564 element = acpi_gbl_global_list->list_head;
565 while (element) {
566 if ((element->component & component) &&
567 ((module == NULL)
568 || (0 == strcmp(module, element->module)))) {
569 descriptor =
570 ACPI_CAST_PTR(union acpi_descriptor,
571 &element->user_space);
572
573 if (element->size <
574 sizeof(struct acpi_common_descriptor)) {
575 acpi_os_printf("%p Length 0x%04X %9.9s-%4.4u "
576 "[Not a Descriptor - too small]\n",
577 descriptor, element->size,
578 element->module, element->line);
579 } else {
580
581
582 if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
583 ACPI_DESC_TYPE_CACHED) {
584 acpi_os_printf
585 ("%p Length 0x%04X %9.9s-%4.4u [%s] ",
586 descriptor, element->size,
587 element->module, element->line,
588 acpi_ut_get_descriptor_name
589 (descriptor));
590
591
592
593 if (acpi_gbl_verbose_leak_dump) {
594 acpi_os_printf("\n");
595 acpi_ut_dump_buffer((u8 *)
596 descriptor,
597 element->
598 size,
599 DB_BYTE_DISPLAY,
600 0);
601 }
602
603
604
605 descriptor_type = 0;
606
607 switch (ACPI_GET_DESCRIPTOR_TYPE
608 (descriptor)) {
609 case ACPI_DESC_TYPE_OPERAND:
610
611 if (element->size ==
612 sizeof(union
613 acpi_operand_object))
614 {
615 descriptor_type =
616 ACPI_DESC_TYPE_OPERAND;
617 }
618 break;
619
620 case ACPI_DESC_TYPE_PARSER:
621
622 if (element->size ==
623 sizeof(union
624 acpi_parse_object)) {
625 descriptor_type =
626 ACPI_DESC_TYPE_PARSER;
627 }
628 break;
629
630 case ACPI_DESC_TYPE_NAMED:
631
632 if (element->size ==
633 sizeof(struct
634 acpi_namespace_node))
635 {
636 descriptor_type =
637 ACPI_DESC_TYPE_NAMED;
638 }
639 break;
640
641 default:
642
643 break;
644 }
645
646
647
648 switch (descriptor_type) {
649 case ACPI_DESC_TYPE_OPERAND:
650
651 acpi_os_printf
652 ("%12.12s RefCount 0x%04X\n",
653 acpi_ut_get_type_name
654 (descriptor->object.common.
655 type),
656 descriptor->object.common.
657 reference_count);
658 break;
659
660 case ACPI_DESC_TYPE_PARSER:
661
662 acpi_os_printf
663 ("AmlOpcode 0x%04hX\n",
664 descriptor->op.asl.
665 aml_opcode);
666 break;
667
668 case ACPI_DESC_TYPE_NAMED:
669
670 acpi_os_printf("%4.4s\n",
671 acpi_ut_get_node_name
672 (&descriptor->
673 node));
674 break;
675
676 default:
677
678 acpi_os_printf("\n");
679 break;
680 }
681 }
682 }
683
684 num_outstanding++;
685 }
686
687 element = element->next;
688 }
689
690 exit:
691 (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
692
693
694
695 if (!num_outstanding) {
696 ACPI_INFO(("No outstanding allocations"));
697 } else {
698 ACPI_ERROR((AE_INFO, "%u (0x%X) Outstanding cache allocations",
699 num_outstanding, num_outstanding));
700 }
701
702 return_VOID;
703 }
704
705 #endif