aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/uttrack.c100
1 files changed, 71 insertions, 29 deletions
diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c
index 79f311c3d1c4..a424a9e3fea4 100644
--- a/drivers/acpi/acpica/uttrack.c
+++ b/drivers/acpi/acpica/uttrack.c
@@ -61,7 +61,9 @@
61ACPI_MODULE_NAME("uttrack") 61ACPI_MODULE_NAME("uttrack")
62 62
63/* Local prototypes */ 63/* Local prototypes */
64static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); 64static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
65 acpi_debug_mem_block
66 *allocation);
65 67
66static acpi_status 68static acpi_status
67acpi_ut_track_allocation(struct acpi_debug_mem_block *address, 69acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
@@ -263,31 +265,61 @@ acpi_ut_free_and_track(void *allocation,
263 * 265 *
264 * PARAMETERS: allocation - Address of allocated memory 266 * PARAMETERS: allocation - Address of allocated memory
265 * 267 *
266 * RETURN: A list element if found; NULL otherwise. 268 * RETURN: Three cases:
269 * 1) List is empty, NULL is returned.
270 * 2) Element was found. Returns Allocation parameter.
271 * 3) Element was not found. Returns position where it should be
272 * inserted into the list.
267 * 273 *
268 * DESCRIPTION: Searches for an element in the global allocation tracking list. 274 * DESCRIPTION: Searches for an element in the global allocation tracking list.
275 * If the element is not found, returns the location within the
276 * list where the element should be inserted.
277 *
278 * Note: The list is ordered by larger-to-smaller addresses.
279 *
280 * This global list is used to detect memory leaks in ACPICA as
281 * well as other issues such as an attempt to release the same
282 * internal object more than once. Although expensive as far
283 * as cpu time, this list is much more helpful for finding these
284 * types of issues than using memory leak detectors outside of
285 * the ACPICA code.
269 * 286 *
270 ******************************************************************************/ 287 ******************************************************************************/
271 288
272static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) 289static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct
290 acpi_debug_mem_block
291 *allocation)
273{ 292{
274 struct acpi_debug_mem_block *element; 293 struct acpi_debug_mem_block *element;
275 294
276 ACPI_FUNCTION_ENTRY();
277
278 element = acpi_gbl_global_list->list_head; 295 element = acpi_gbl_global_list->list_head;
296 if (!element) {
297 return (NULL);
298 }
299
300 /*
301 * Search for the address.
302 *
303 * Note: List is ordered by larger-to-smaller addresses, on the
304 * assumption that a new allocation usually has a larger address
305 * than previous allocations.
306 */
307 while (element > allocation) {
279 308
280 /* Search for the address. */ 309 /* Check for end-of-list */
281 310
282 while (element) { 311 if (!element->next) {
283 if (element == allocation) {
284 return (element); 312 return (element);
285 } 313 }
286 314
287 element = element->next; 315 element = element->next;
288 } 316 }
289 317
290 return (NULL); 318 if (element == allocation) {
319 return (element);
320 }
321
322 return (element->previous);
291} 323}
292 324
293/******************************************************************************* 325/*******************************************************************************
@@ -301,7 +333,7 @@ static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation)
301 * module - Source file name of caller 333 * module - Source file name of caller
302 * line - Line number of caller 334 * line - Line number of caller
303 * 335 *
304 * RETURN: None. 336 * RETURN: Status
305 * 337 *
306 * DESCRIPTION: Inserts an element into the global allocation tracking list. 338 * DESCRIPTION: Inserts an element into the global allocation tracking list.
307 * 339 *
@@ -330,22 +362,18 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
330 } 362 }
331 363
332 /* 364 /*
333 * Search list for this address to make sure it is not already on the list. 365 * Search the global list for this address to make sure it is not
334 * This will catch several kinds of problems. 366 * already present. This will catch several kinds of problems.
335 */ 367 */
336 element = acpi_ut_find_allocation(allocation); 368 element = acpi_ut_find_allocation(allocation);
337 if (element) { 369 if (element == allocation) {
338 ACPI_ERROR((AE_INFO, 370 ACPI_ERROR((AE_INFO,
339 "UtTrackAllocation: Allocation already present in list! (%p)", 371 "UtTrackAllocation: Allocation (%p) already present in global list!",
340 allocation)); 372 allocation));
341
342 ACPI_ERROR((AE_INFO, "Element %p Address %p",
343 element, allocation));
344
345 goto unlock_and_exit; 373 goto unlock_and_exit;
346 } 374 }
347 375
348 /* Fill in the instance data. */ 376 /* Fill in the instance data */
349 377
350 allocation->size = (u32)size; 378 allocation->size = (u32)size;
351 allocation->alloc_type = alloc_type; 379 allocation->alloc_type = alloc_type;
@@ -355,17 +383,31 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
355 ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME); 383 ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME);
356 allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0; 384 allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
357 385
358 /* Insert at list head */ 386 if (!element) {
359 387
360 if (mem_list->list_head) { 388 /* Insert at list head */
361 ((struct acpi_debug_mem_block *)(mem_list->list_head))-> 389
362 previous = allocation; 390 if (mem_list->list_head) {
363 } 391 ((struct acpi_debug_mem_block *)(mem_list->list_head))->
392 previous = allocation;
393 }
394
395 allocation->next = mem_list->list_head;
396 allocation->previous = NULL;
364 397
365 allocation->next = mem_list->list_head; 398 mem_list->list_head = allocation;
366 allocation->previous = NULL; 399 } else {
400 /* Insert after element */
401
402 allocation->next = element->next;
403 allocation->previous = element;
404
405 if (element->next) {
406 (element->next)->previous = allocation;
407 }
367 408
368 mem_list->list_head = allocation; 409 element->next = allocation;
410 }
369 411
370 unlock_and_exit: 412 unlock_and_exit:
371 status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); 413 status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
@@ -381,7 +423,7 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
381 * module - Source file name of caller 423 * module - Source file name of caller
382 * line - Line number of caller 424 * line - Line number of caller
383 * 425 *
384 * RETURN: 426 * RETURN: Status
385 * 427 *
386 * DESCRIPTION: Deletes an element from the global allocation tracking list. 428 * DESCRIPTION: Deletes an element from the global allocation tracking list.
387 * 429 *
@@ -443,7 +485,7 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
443 * 485 *
444 * FUNCTION: acpi_ut_dump_allocation_info 486 * FUNCTION: acpi_ut_dump_allocation_info
445 * 487 *
446 * PARAMETERS: 488 * PARAMETERS: None
447 * 489 *
448 * RETURN: None 490 * RETURN: None
449 * 491 *