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