diff options
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/uttrack.c | 100 |
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 @@ | |||
61 | ACPI_MODULE_NAME("uttrack") | 61 | ACPI_MODULE_NAME("uttrack") |
62 | 62 | ||
63 | /* Local prototypes */ | 63 | /* Local prototypes */ |
64 | static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); | 64 | static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct |
65 | acpi_debug_mem_block | ||
66 | *allocation); | ||
65 | 67 | ||
66 | static acpi_status | 68 | static acpi_status |
67 | acpi_ut_track_allocation(struct acpi_debug_mem_block *address, | 69 | acpi_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 | ||
272 | static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) | 289 | static 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 | * |