Blame view

drivers/acpi/acpica/uttrack.c 20 KB
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
1
2
3
4
5
6
7
  /******************************************************************************
   *
   * Module Name: uttrack - Memory allocation tracking routines (debug only)
   *
   *****************************************************************************/
  
  /*
c8100dc46   Bob Moore   ACPICA: Additiona...
8
   * Copyright (C) 2000 - 2016, Intel Corp.
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
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
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions, and the following disclaimer,
   *    without modification.
   * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   *    substantially similar to the "NO WARRANTY" disclaimer below
   *    ("Disclaimer") and any redistribution must be conditioned upon
   *    including a substantially similar Disclaimer requirement for further
   *    binary redistribution.
   * 3. Neither the names of the above-listed copyright holders nor the names
   *    of any contributors may be used to endorse or promote products derived
   *    from this software without specific prior written permission.
   *
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * NO WARRANTY
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGES.
   */
  
  /*
   * These procedures are used for tracking memory leaks in the subsystem, and
   * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
   *
73a3090a2   Bob Moore   ACPICA: Remove ex...
48
   * Each memory allocation is tracked via a doubly linked list. Each
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
49
   * element contains the caller's component, module name, function name, and
73a3090a2   Bob Moore   ACPICA: Remove ex...
50
   * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
51
52
53
54
55
56
57
58
59
60
61
62
63
   * acpi_ut_track_allocation to add an element to the list; deletion
   * occurs in the body of acpi_ut_free.
   */
  
  #include <acpi/acpi.h>
  #include "accommon.h"
  
  #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  
  #define _COMPONENT          ACPI_UTILITIES
  ACPI_MODULE_NAME("uttrack")
  
  /* Local prototypes */
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
64
65
66
  static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
  							    acpi_debug_mem_block
  							    *allocation);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  
  static acpi_status
  acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
  			 acpi_size size,
  			 u8 alloc_type,
  			 u32 component, const char *module, u32 line);
  
  static acpi_status
  acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
  			  u32 component, const char *module, u32 line);
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_create_list
   *
   * PARAMETERS:  cache_name      - Ascii name for the cache
   *              object_size     - Size of each cached object
   *              return_cache    - Where the new cache object is returned
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Create a local memory list for tracking purposed
   *
   ******************************************************************************/
  
  acpi_status
0dfaaa3d5   Bob Moore   ACPICA: All: cons...
93
  acpi_ut_create_list(const char *list_name,
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
94
95
96
  		    u16 object_size, struct acpi_memory_list **return_cache)
  {
  	struct acpi_memory_list *cache;
9556ec4ec   Bob Moore   ACPICA: Use os_al...
97
  	cache = acpi_os_allocate_zeroed(sizeof(struct acpi_memory_list));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
98
99
100
  	if (!cache) {
  		return (AE_NO_MEMORY);
  	}
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  	cache->list_name = list_name;
  	cache->object_size = object_size;
  
  	*return_cache = cache;
  	return (AE_OK);
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_allocate_and_track
   *
   * PARAMETERS:  size                - Size of the allocation
   *              component           - Component type of caller
   *              module              - Source file name of caller
   *              line                - Line number of caller
   *
   * RETURN:      Address of the allocated memory on success, NULL on failure.
   *
   * DESCRIPTION: The subsystem's equivalent of malloc.
   *
   ******************************************************************************/
  
  void *acpi_ut_allocate_and_track(acpi_size size,
  				 u32 component, const char *module, u32 line)
  {
  	struct acpi_debug_mem_block *allocation;
  	acpi_status status;
b3c86c30e   Lv Zheng   ACPICA: Cleanup m...
128
129
130
131
132
133
134
  	/* Check for an inadvertent size of zero bytes */
  
  	if (!size) {
  		ACPI_WARNING((module, line,
  			      "Attempt to allocate zero bytes, allocating 1 byte"));
  		size = 1;
  	}
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
135
  	allocation =
b3c86c30e   Lv Zheng   ACPICA: Cleanup m...
136
  	    acpi_os_allocate(size + sizeof(struct acpi_debug_mem_header));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
137
  	if (!allocation) {
b3c86c30e   Lv Zheng   ACPICA: Cleanup m...
138
139
140
141
142
  
  		/* Report allocation error */
  
  		ACPI_WARNING((module, line,
  			      "Could not allocate size %u", (u32)size));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
143
144
  		return (NULL);
  	}
1fad87385   Bob Moore   ACPICA: Core: Maj...
145
146
147
  	status =
  	    acpi_ut_track_allocation(allocation, size, ACPI_MEM_MALLOC,
  				     component, module, line);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
148
149
150
151
152
153
154
155
  	if (ACPI_FAILURE(status)) {
  		acpi_os_free(allocation);
  		return (NULL);
  	}
  
  	acpi_gbl_global_list->total_allocated++;
  	acpi_gbl_global_list->total_size += (u32)size;
  	acpi_gbl_global_list->current_total_size += (u32)size;
1fad87385   Bob Moore   ACPICA: Core: Maj...
156

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  	if (acpi_gbl_global_list->current_total_size >
  	    acpi_gbl_global_list->max_occupied) {
  		acpi_gbl_global_list->max_occupied =
  		    acpi_gbl_global_list->current_total_size;
  	}
  
  	return ((void *)&allocation->user_space);
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_allocate_zeroed_and_track
   *
   * PARAMETERS:  size                - Size of the allocation
   *              component           - Component type of caller
   *              module              - Source file name of caller
   *              line                - Line number of caller
   *
   * RETURN:      Address of the allocated memory on success, NULL on failure.
   *
   * DESCRIPTION: Subsystem equivalent of calloc.
   *
   ******************************************************************************/
  
  void *acpi_ut_allocate_zeroed_and_track(acpi_size size,
  					u32 component,
  					const char *module, u32 line)
  {
  	struct acpi_debug_mem_block *allocation;
  	acpi_status status;
b3c86c30e   Lv Zheng   ACPICA: Cleanup m...
187
188
189
190
191
192
193
  	/* Check for an inadvertent size of zero bytes */
  
  	if (!size) {
  		ACPI_WARNING((module, line,
  			      "Attempt to allocate zero bytes, allocating 1 byte"));
  		size = 1;
  	}
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
194
  	allocation =
b3c86c30e   Lv Zheng   ACPICA: Cleanup m...
195
196
  	    acpi_os_allocate_zeroed(size +
  				    sizeof(struct acpi_debug_mem_header));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  	if (!allocation) {
  
  		/* Report allocation error */
  
  		ACPI_ERROR((module, line,
  			    "Could not allocate size %u", (u32)size));
  		return (NULL);
  	}
  
  	status = acpi_ut_track_allocation(allocation, size,
  					  ACPI_MEM_CALLOC, component, module,
  					  line);
  	if (ACPI_FAILURE(status)) {
  		acpi_os_free(allocation);
  		return (NULL);
  	}
  
  	acpi_gbl_global_list->total_allocated++;
  	acpi_gbl_global_list->total_size += (u32)size;
  	acpi_gbl_global_list->current_total_size += (u32)size;
1fad87385   Bob Moore   ACPICA: Core: Maj...
217

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  	if (acpi_gbl_global_list->current_total_size >
  	    acpi_gbl_global_list->max_occupied) {
  		acpi_gbl_global_list->max_occupied =
  		    acpi_gbl_global_list->current_total_size;
  	}
  
  	return ((void *)&allocation->user_space);
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_free_and_track
   *
   * PARAMETERS:  allocation          - Address of the memory to deallocate
   *              component           - Component type of caller
   *              module              - Source file name of caller
   *              line                - Line number of caller
   *
   * RETURN:      None
   *
   * DESCRIPTION: Frees the memory at Allocation
   *
   ******************************************************************************/
  
  void
  acpi_ut_free_and_track(void *allocation,
  		       u32 component, const char *module, u32 line)
  {
  	struct acpi_debug_mem_block *debug_block;
  	acpi_status status;
  
  	ACPI_FUNCTION_TRACE_PTR(ut_free, allocation);
  
  	if (NULL == allocation) {
  		ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
  
  		return_VOID;
  	}
  
  	debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
  				    (((char *)allocation) -
  				     sizeof(struct acpi_debug_mem_header)));
  
  	acpi_gbl_global_list->total_freed++;
  	acpi_gbl_global_list->current_total_size -= debug_block->size;
1fad87385   Bob Moore   ACPICA: Core: Maj...
263
264
  	status =
  	    acpi_ut_remove_allocation(debug_block, component, module, line);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
265
266
267
268
269
  	if (ACPI_FAILURE(status)) {
  		ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
  	}
  
  	acpi_os_free(debug_block);
d72c17a86   Bob Moore   ACPICA: Utilities...
270
271
272
  	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed (block %p)
  ",
  			  allocation, debug_block));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
273
274
275
276
277
278
279
280
281
  	return_VOID;
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_find_allocation
   *
   * PARAMETERS:  allocation              - Address of allocated memory
   *
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
282
283
284
285
286
   * RETURN:      Three cases:
   *              1) List is empty, NULL is returned.
   *              2) Element was found. Returns Allocation parameter.
   *              3) Element was not found. Returns position where it should be
   *                  inserted into the list.
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
287
288
   *
   * DESCRIPTION: Searches for an element in the global allocation tracking list.
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
289
290
291
292
293
294
295
296
297
298
299
   *              If the element is not found, returns the location within the
   *              list where the element should be inserted.
   *
   *              Note: The list is ordered by larger-to-smaller addresses.
   *
   *              This global list is used to detect memory leaks in ACPICA as
   *              well as other issues such as an attempt to release the same
   *              internal object more than once. Although expensive as far
   *              as cpu time, this list is much more helpful for finding these
   *              types of issues than using memory leak detectors outside of
   *              the ACPICA code.
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
300
301
   *
   ******************************************************************************/
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
302
303
304
  static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
  							    acpi_debug_mem_block
  							    *allocation)
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
305
306
  {
  	struct acpi_debug_mem_block *element;
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
307
  	element = acpi_gbl_global_list->list_head;
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
308
309
310
311
312
313
314
315
316
317
318
319
  	if (!element) {
  		return (NULL);
  	}
  
  	/*
  	 * Search for the address.
  	 *
  	 * Note: List is ordered by larger-to-smaller addresses, on the
  	 * assumption that a new allocation usually has a larger address
  	 * than previous allocations.
  	 */
  	while (element > allocation) {
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
320

d8da9151b   Bob Moore   ACPICA: AcpiExec:...
321
  		/* Check for end-of-list */
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
322

d8da9151b   Bob Moore   ACPICA: AcpiExec:...
323
  		if (!element->next) {
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
324
325
326
327
328
  			return (element);
  		}
  
  		element = element->next;
  	}
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
329
330
331
332
333
  	if (element == allocation) {
  		return (element);
  	}
  
  	return (element->previous);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
334
335
336
337
338
339
340
341
342
343
344
345
346
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_track_allocation
   *
   * PARAMETERS:  allocation          - Address of allocated memory
   *              size                - Size of the allocation
   *              alloc_type          - MEM_MALLOC or MEM_CALLOC
   *              component           - Component type of caller
   *              module              - Source file name of caller
   *              line                - Line number of caller
   *
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
347
   * RETURN:      Status
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
   *
   * DESCRIPTION: Inserts an element into the global allocation tracking list.
   *
   ******************************************************************************/
  
  static acpi_status
  acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
  			 acpi_size size,
  			 u8 alloc_type,
  			 u32 component, const char *module, u32 line)
  {
  	struct acpi_memory_list *mem_list;
  	struct acpi_debug_mem_block *element;
  	acpi_status status = AE_OK;
  
  	ACPI_FUNCTION_TRACE_PTR(ut_track_allocation, allocation);
  
  	if (acpi_gbl_disable_mem_tracking) {
  		return_ACPI_STATUS(AE_OK);
  	}
  
  	mem_list = acpi_gbl_global_list;
  	status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  	if (ACPI_FAILURE(status)) {
  		return_ACPI_STATUS(status);
  	}
  
  	/*
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
376
377
  	 * Search the global list for this address to make sure it is not
  	 * already present. This will catch several kinds of problems.
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
378
379
  	 */
  	element = acpi_ut_find_allocation(allocation);
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
380
  	if (element == allocation) {
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
381
  		ACPI_ERROR((AE_INFO,
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
382
  			    "UtTrackAllocation: Allocation (%p) already present in global list!",
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
383
  			    allocation));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
384
385
  		goto unlock_and_exit;
  	}
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
386
  	/* Fill in the instance data */
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
387
388
389
390
391
  
  	allocation->size = (u32)size;
  	allocation->alloc_type = alloc_type;
  	allocation->component = component;
  	allocation->line = line;
4fa4616e2   Bob Moore   ACPICA: De-macroi...
392
  	strncpy(allocation->module, module, ACPI_MAX_MODULE_NAME);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
393
  	allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
394
  	if (!element) {
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
395

d8da9151b   Bob Moore   ACPICA: AcpiExec:...
396
397
398
399
400
401
402
403
404
  		/* Insert at list head */
  
  		if (mem_list->list_head) {
  			((struct acpi_debug_mem_block *)(mem_list->list_head))->
  			    previous = allocation;
  		}
  
  		allocation->next = mem_list->list_head;
  		allocation->previous = NULL;
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
405

d8da9151b   Bob Moore   ACPICA: AcpiExec:...
406
407
408
  		mem_list->list_head = allocation;
  	} else {
  		/* Insert after element */
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
409

d8da9151b   Bob Moore   ACPICA: AcpiExec:...
410
411
412
413
414
415
416
417
418
  		allocation->next = element->next;
  		allocation->previous = element;
  
  		if (element->next) {
  			(element->next)->previous = allocation;
  		}
  
  		element->next = allocation;
  	}
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
419

10622bf8c   Lv Zheng   ACPICA: Linuxize:...
420
  unlock_and_exit:
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
421
422
423
424
425
426
427
428
429
430
431
432
433
  	status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  	return_ACPI_STATUS(status);
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_remove_allocation
   *
   * PARAMETERS:  allocation          - Address of allocated memory
   *              component           - Component type of caller
   *              module              - Source file name of caller
   *              line                - Line number of caller
   *
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
434
   * RETURN:      Status
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
435
436
437
438
439
440
441
442
443
444
445
   *
   * DESCRIPTION: Deletes an element from the global allocation tracking list.
   *
   ******************************************************************************/
  
  static acpi_status
  acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
  			  u32 component, const char *module, u32 line)
  {
  	struct acpi_memory_list *mem_list;
  	acpi_status status;
0e770b326   Bob Moore   ACPICA: Performan...
446
  	ACPI_FUNCTION_NAME(ut_remove_allocation);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
447
448
  
  	if (acpi_gbl_disable_mem_tracking) {
0e770b326   Bob Moore   ACPICA: Performan...
449
  		return (AE_OK);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
450
451
452
453
454
455
456
457
458
  	}
  
  	mem_list = acpi_gbl_global_list;
  	if (NULL == mem_list->list_head) {
  
  		/* No allocations! */
  
  		ACPI_ERROR((module, line,
  			    "Empty allocation list, nothing to free!"));
0e770b326   Bob Moore   ACPICA: Performan...
459
  		return (AE_OK);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
460
461
462
463
  	}
  
  	status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  	if (ACPI_FAILURE(status)) {
0e770b326   Bob Moore   ACPICA: Performan...
464
  		return (status);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
465
466
467
468
469
470
471
472
473
474
475
476
477
  	}
  
  	/* Unlink */
  
  	if (allocation->previous) {
  		(allocation->previous)->next = allocation->next;
  	} else {
  		mem_list->list_head = allocation->next;
  	}
  
  	if (allocation->next) {
  		(allocation->next)->previous = allocation->previous;
  	}
0e770b326   Bob Moore   ACPICA: Performan...
478
479
480
  	ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X
  ",
  			  &allocation->user_space, allocation->size));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
481
  	/* Mark the segment as deleted */
4fa4616e2   Bob Moore   ACPICA: De-macroi...
482
  	memset(&allocation->user_space, 0xEA, allocation->size);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
483

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
484
  	status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
0e770b326   Bob Moore   ACPICA: Performan...
485
  	return (status);
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
486
487
488
489
490
491
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_dump_allocation_info
   *
d8da9151b   Bob Moore   ACPICA: AcpiExec:...
492
   * PARAMETERS:  None
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
   *
   * RETURN:      None
   *
   * DESCRIPTION: Print some info about the outstanding allocations.
   *
   ******************************************************************************/
  
  void acpi_ut_dump_allocation_info(void)
  {
  /*
  	struct acpi_memory_list         *mem_list;
  */
  
  	ACPI_FUNCTION_TRACE(ut_dump_allocation_info);
  
  /*
  	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
1fad87385   Bob Moore   ACPICA: Core: Maj...
510
511
512
513
  		("%30s: %4d (%3d Kb)
  ", "Current allocations",
  		mem_list->current_count,
  		ROUND_UP_TO_1K (mem_list->current_size)));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
514
515
  
  	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
1fad87385   Bob Moore   ACPICA: Core: Maj...
516
517
518
519
  		("%30s: %4d (%3d Kb)
  ", "Max concurrent allocations",
  		mem_list->max_concurrent_count,
  		ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
520
521
  
  	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
1fad87385   Bob Moore   ACPICA: Core: Maj...
522
523
524
525
  		("%30s: %4d (%3d Kb)
  ", "Total (all) internal objects",
  		running_object_count,
  		ROUND_UP_TO_1K (running_object_size)));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
526
527
  
  	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
1fad87385   Bob Moore   ACPICA: Core: Maj...
528
529
530
531
  		("%30s: %4d (%3d Kb)
  ", "Total (all) allocations",
  		running_alloc_count,
  		ROUND_UP_TO_1K (running_alloc_size)));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
532
533
  
  	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
1fad87385   Bob Moore   ACPICA: Core: Maj...
534
535
536
537
  		("%30s: %4d (%3d Kb)
  ", "Current Nodes",
  		acpi_gbl_current_node_count,
  		ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
538
539
  
  	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
1fad87385   Bob Moore   ACPICA: Core: Maj...
540
541
542
543
544
  		("%30s: %4d (%3d Kb)
  ", "Max Nodes",
  		acpi_gbl_max_concurrent_node_count,
  		ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
  			sizeof (struct acpi_namespace_node)))));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
545
546
547
548
549
550
551
552
553
  */
  	return_VOID;
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_ut_dump_allocations
   *
   * PARAMETERS:  component           - Component(s) to dump info for.
73a3090a2   Bob Moore   ACPICA: Remove ex...
554
   *              module              - Module to dump info for. NULL means all.
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
   *
   * RETURN:      None
   *
   * DESCRIPTION: Print a list of all outstanding allocations.
   *
   ******************************************************************************/
  
  void acpi_ut_dump_allocations(u32 component, const char *module)
  {
  	struct acpi_debug_mem_block *element;
  	union acpi_descriptor *descriptor;
  	u32 num_outstanding = 0;
  	u8 descriptor_type;
  
  	ACPI_FUNCTION_TRACE(ut_dump_allocations);
  
  	if (acpi_gbl_disable_mem_tracking) {
68aafc351   Bob Moore   ACPICA: Audit/upd...
572
  		return_VOID;
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
573
574
575
576
577
578
  	}
  
  	/*
  	 * Walk the allocation list.
  	 */
  	if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
68aafc351   Bob Moore   ACPICA: Audit/upd...
579
  		return_VOID;
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
580
581
582
583
584
585
  	}
  
  	element = acpi_gbl_global_list->list_head;
  	while (element) {
  		if ((element->component & component) &&
  		    ((module == NULL)
4fa4616e2   Bob Moore   ACPICA: De-macroi...
586
  		     || (0 == strcmp(module, element->module)))) {
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
  			descriptor =
  			    ACPI_CAST_PTR(union acpi_descriptor,
  					  &element->user_space);
  
  			if (element->size <
  			    sizeof(struct acpi_common_descriptor)) {
  				acpi_os_printf("%p Length 0x%04X %9.9s-%u "
  					       "[Not a Descriptor - too small]
  ",
  					       descriptor, element->size,
  					       element->module, element->line);
  			} else {
  				/* Ignore allocated objects that are in a cache */
  
  				if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
  				    ACPI_DESC_TYPE_CACHED) {
  					acpi_os_printf
  					    ("%p Length 0x%04X %9.9s-%u [%s] ",
  					     descriptor, element->size,
  					     element->module, element->line,
  					     acpi_ut_get_descriptor_name
  					     (descriptor));
  
  					/* Validate the descriptor type using Type field and length */
  
  					descriptor_type = 0;	/* Not a valid descriptor type */
  
  					switch (ACPI_GET_DESCRIPTOR_TYPE
  						(descriptor)) {
  					case ACPI_DESC_TYPE_OPERAND:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
617

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
618
619
620
621
622
623
624
625
626
627
  						if (element->size ==
  						    sizeof(union
  							   acpi_operand_object))
  						{
  							descriptor_type =
  							    ACPI_DESC_TYPE_OPERAND;
  						}
  						break;
  
  					case ACPI_DESC_TYPE_PARSER:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
628

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
629
630
631
632
633
634
635
636
637
  						if (element->size ==
  						    sizeof(union
  							   acpi_parse_object)) {
  							descriptor_type =
  							    ACPI_DESC_TYPE_PARSER;
  						}
  						break;
  
  					case ACPI_DESC_TYPE_NAMED:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
638

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
639
640
641
642
643
644
645
646
647
648
  						if (element->size ==
  						    sizeof(struct
  							   acpi_namespace_node))
  						{
  							descriptor_type =
  							    ACPI_DESC_TYPE_NAMED;
  						}
  						break;
  
  					default:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
649

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
650
651
652
653
654
655
656
  						break;
  					}
  
  					/* Display additional info for the major descriptor types */
  
  					switch (descriptor_type) {
  					case ACPI_DESC_TYPE_OPERAND:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
657

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
658
659
660
661
662
663
664
665
666
667
668
  						acpi_os_printf
  						    ("%12.12s RefCount 0x%04X
  ",
  						     acpi_ut_get_type_name
  						     (descriptor->object.common.
  						      type),
  						     descriptor->object.common.
  						     reference_count);
  						break;
  
  					case ACPI_DESC_TYPE_PARSER:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
669

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
670
671
672
673
674
675
676
677
  						acpi_os_printf
  						    ("AmlOpcode 0x%04hX
  ",
  						     descriptor->op.asl.
  						     aml_opcode);
  						break;
  
  					case ACPI_DESC_TYPE_NAMED:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
678

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
679
680
681
682
683
684
685
686
  						acpi_os_printf("%4.4s
  ",
  							       acpi_ut_get_node_name
  							       (&descriptor->
  								node));
  						break;
  
  					default:
1d1ea1b72   Chao Guan   ACPICA: Standardi...
687

6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
  						acpi_os_printf("
  ");
  						break;
  					}
  				}
  			}
  
  			num_outstanding++;
  		}
  
  		element = element->next;
  	}
  
  	(void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  
  	/* Print summary */
  
  	if (!num_outstanding) {
05fb04b54   Bob Moore   ACPICA: Remove un...
706
  		ACPI_INFO(("No outstanding allocations"));
6d33b6be1   Lv Zheng   ACPICA: Fix unmer...
707
708
709
710
711
712
713
714
715
  	} else {
  		ACPI_ERROR((AE_INFO, "%u(0x%X) Outstanding allocations",
  			    num_outstanding, num_outstanding));
  	}
  
  	return_VOID;
  }
  
  #endif				/* ACPI_DBG_TRACK_ALLOCATIONS */