utalloc.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. /******************************************************************************
  2. *
  3. * Module Name: utalloc - local memory allocation routines
  4. *
  5. *****************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2006, R. Byron Moore
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions, and the following disclaimer,
  15. * without modification.
  16. * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  17. * substantially similar to the "NO WARRANTY" disclaimer below
  18. * ("Disclaimer") and any redistribution must be conditioned upon
  19. * including a substantially similar Disclaimer requirement for further
  20. * binary redistribution.
  21. * 3. Neither the names of the above-listed copyright holders nor the names
  22. * of any contributors may be used to endorse or promote products derived
  23. * from this software without specific prior written permission.
  24. *
  25. * Alternatively, this software may be distributed under the terms of the
  26. * GNU General Public License ("GPL") version 2 as published by the Free
  27. * Software Foundation.
  28. *
  29. * NO WARRANTY
  30. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  33. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  34. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  38. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  39. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  40. * POSSIBILITY OF SUCH DAMAGES.
  41. */
  42. #include <acpi/acpi.h>
  43. #define _COMPONENT ACPI_UTILITIES
  44. ACPI_MODULE_NAME("utalloc")
  45. /* Local prototypes */
  46. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  47. static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation);
  48. static acpi_status
  49. acpi_ut_track_allocation(struct acpi_debug_mem_block *address,
  50. acpi_size size,
  51. u8 alloc_type, u32 component, char *module, u32 line);
  52. static acpi_status
  53. acpi_ut_remove_allocation(struct acpi_debug_mem_block *address,
  54. u32 component, char *module, u32 line);
  55. static acpi_status
  56. acpi_ut_create_list(char *list_name,
  57. u16 object_size, struct acpi_memory_list **return_cache);
  58. #endif
  59. /*******************************************************************************
  60. *
  61. * FUNCTION: acpi_ut_create_caches
  62. *
  63. * PARAMETERS: None
  64. *
  65. * RETURN: Status
  66. *
  67. * DESCRIPTION: Create all local caches
  68. *
  69. ******************************************************************************/
  70. acpi_status acpi_ut_create_caches(void)
  71. {
  72. acpi_status status;
  73. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  74. /* Memory allocation lists */
  75. status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
  76. if (ACPI_FAILURE(status)) {
  77. return (status);
  78. }
  79. status =
  80. acpi_ut_create_list("Acpi-Namespace",
  81. sizeof(struct acpi_namespace_node),
  82. &acpi_gbl_ns_node_list);
  83. if (ACPI_FAILURE(status)) {
  84. return (status);
  85. }
  86. #endif
  87. /* Object Caches, for frequently used objects */
  88. status =
  89. acpi_os_create_cache("acpi_state", sizeof(union acpi_generic_state),
  90. ACPI_MAX_STATE_CACHE_DEPTH,
  91. &acpi_gbl_state_cache);
  92. if (ACPI_FAILURE(status)) {
  93. return (status);
  94. }
  95. status =
  96. acpi_os_create_cache("acpi_parse",
  97. sizeof(struct acpi_parse_obj_common),
  98. ACPI_MAX_PARSE_CACHE_DEPTH,
  99. &acpi_gbl_ps_node_cache);
  100. if (ACPI_FAILURE(status)) {
  101. return (status);
  102. }
  103. status =
  104. acpi_os_create_cache("acpi_parse_ext",
  105. sizeof(struct acpi_parse_obj_named),
  106. ACPI_MAX_EXTPARSE_CACHE_DEPTH,
  107. &acpi_gbl_ps_node_ext_cache);
  108. if (ACPI_FAILURE(status)) {
  109. return (status);
  110. }
  111. status =
  112. acpi_os_create_cache("acpi_operand",
  113. sizeof(union acpi_operand_object),
  114. ACPI_MAX_OBJECT_CACHE_DEPTH,
  115. &acpi_gbl_operand_cache);
  116. if (ACPI_FAILURE(status)) {
  117. return (status);
  118. }
  119. return (AE_OK);
  120. }
  121. /*******************************************************************************
  122. *
  123. * FUNCTION: acpi_ut_delete_caches
  124. *
  125. * PARAMETERS: None
  126. *
  127. * RETURN: Status
  128. *
  129. * DESCRIPTION: Purge and delete all local caches
  130. *
  131. ******************************************************************************/
  132. acpi_status acpi_ut_delete_caches(void)
  133. {
  134. (void)acpi_os_delete_cache(acpi_gbl_state_cache);
  135. acpi_gbl_state_cache = NULL;
  136. (void)acpi_os_delete_cache(acpi_gbl_operand_cache);
  137. acpi_gbl_operand_cache = NULL;
  138. (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
  139. acpi_gbl_ps_node_cache = NULL;
  140. (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
  141. acpi_gbl_ps_node_ext_cache = NULL;
  142. return (AE_OK);
  143. }
  144. /*******************************************************************************
  145. *
  146. * FUNCTION: acpi_ut_validate_buffer
  147. *
  148. * PARAMETERS: Buffer - Buffer descriptor to be validated
  149. *
  150. * RETURN: Status
  151. *
  152. * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
  153. *
  154. ******************************************************************************/
  155. acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer)
  156. {
  157. /* Obviously, the structure pointer must be valid */
  158. if (!buffer) {
  159. return (AE_BAD_PARAMETER);
  160. }
  161. /* Special semantics for the length */
  162. if ((buffer->length == ACPI_NO_BUFFER) ||
  163. (buffer->length == ACPI_ALLOCATE_BUFFER) ||
  164. (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
  165. return (AE_OK);
  166. }
  167. /* Length is valid, the buffer pointer must be also */
  168. if (!buffer->pointer) {
  169. return (AE_BAD_PARAMETER);
  170. }
  171. return (AE_OK);
  172. }
  173. /*******************************************************************************
  174. *
  175. * FUNCTION: acpi_ut_initialize_buffer
  176. *
  177. * PARAMETERS: Buffer - Buffer to be validated
  178. * required_length - Length needed
  179. *
  180. * RETURN: Status
  181. *
  182. * DESCRIPTION: Validate that the buffer is of the required length or
  183. * allocate a new buffer. Returned buffer is always zeroed.
  184. *
  185. ******************************************************************************/
  186. acpi_status
  187. acpi_ut_initialize_buffer(struct acpi_buffer * buffer,
  188. acpi_size required_length)
  189. {
  190. acpi_status status = AE_OK;
  191. switch (buffer->length) {
  192. case ACPI_NO_BUFFER:
  193. /* Set the exception and returned the required length */
  194. status = AE_BUFFER_OVERFLOW;
  195. break;
  196. case ACPI_ALLOCATE_BUFFER:
  197. /* Allocate a new buffer */
  198. buffer->pointer = acpi_os_allocate(required_length);
  199. if (!buffer->pointer) {
  200. return (AE_NO_MEMORY);
  201. }
  202. /* Clear the buffer */
  203. ACPI_MEMSET(buffer->pointer, 0, required_length);
  204. break;
  205. case ACPI_ALLOCATE_LOCAL_BUFFER:
  206. /* Allocate a new buffer with local interface to allow tracking */
  207. buffer->pointer = ACPI_MEM_CALLOCATE(required_length);
  208. if (!buffer->pointer) {
  209. return (AE_NO_MEMORY);
  210. }
  211. break;
  212. default:
  213. /* Existing buffer: Validate the size of the buffer */
  214. if (buffer->length < required_length) {
  215. status = AE_BUFFER_OVERFLOW;
  216. break;
  217. }
  218. /* Clear the buffer */
  219. ACPI_MEMSET(buffer->pointer, 0, required_length);
  220. break;
  221. }
  222. buffer->length = required_length;
  223. return (status);
  224. }
  225. /*******************************************************************************
  226. *
  227. * FUNCTION: acpi_ut_allocate
  228. *
  229. * PARAMETERS: Size - Size of the allocation
  230. * Component - Component type of caller
  231. * Module - Source file name of caller
  232. * Line - Line number of caller
  233. *
  234. * RETURN: Address of the allocated memory on success, NULL on failure.
  235. *
  236. * DESCRIPTION: The subsystem's equivalent of malloc.
  237. *
  238. ******************************************************************************/
  239. void *acpi_ut_allocate(acpi_size size, u32 component, char *module, u32 line)
  240. {
  241. void *allocation;
  242. ACPI_FUNCTION_TRACE_U32("ut_allocate", size);
  243. /* Check for an inadvertent size of zero bytes */
  244. if (!size) {
  245. ACPI_ERROR((module, line,
  246. "ut_allocate: Attempt to allocate zero bytes, allocating 1 byte"));
  247. size = 1;
  248. }
  249. allocation = acpi_os_allocate(size);
  250. if (!allocation) {
  251. /* Report allocation error */
  252. ACPI_ERROR((module, line,
  253. "ut_allocate: Could not allocate size %X",
  254. (u32) size));
  255. return_PTR(NULL);
  256. }
  257. return_PTR(allocation);
  258. }
  259. /*******************************************************************************
  260. *
  261. * FUNCTION: acpi_ut_callocate
  262. *
  263. * PARAMETERS: Size - Size of the allocation
  264. * Component - Component type of caller
  265. * Module - Source file name of caller
  266. * Line - Line number of caller
  267. *
  268. * RETURN: Address of the allocated memory on success, NULL on failure.
  269. *
  270. * DESCRIPTION: Subsystem equivalent of calloc.
  271. *
  272. ******************************************************************************/
  273. void *acpi_ut_callocate(acpi_size size, u32 component, char *module, u32 line)
  274. {
  275. void *allocation;
  276. ACPI_FUNCTION_TRACE_U32("ut_callocate", size);
  277. /* Check for an inadvertent size of zero bytes */
  278. if (!size) {
  279. ACPI_ERROR((module, line,
  280. "Attempt to allocate zero bytes, allocating 1 byte"));
  281. size = 1;
  282. }
  283. allocation = acpi_os_allocate(size);
  284. if (!allocation) {
  285. /* Report allocation error */
  286. ACPI_ERROR((module, line,
  287. "Could not allocate size %X", (u32) size));
  288. return_PTR(NULL);
  289. }
  290. /* Clear the memory block */
  291. ACPI_MEMSET(allocation, 0, size);
  292. return_PTR(allocation);
  293. }
  294. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  295. /*
  296. * These procedures are used for tracking memory leaks in the subsystem, and
  297. * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
  298. *
  299. * Each memory allocation is tracked via a doubly linked list. Each
  300. * element contains the caller's component, module name, function name, and
  301. * line number. acpi_ut_allocate and acpi_ut_callocate call
  302. * acpi_ut_track_allocation to add an element to the list; deletion
  303. * occurs in the body of acpi_ut_free.
  304. */
  305. /*******************************************************************************
  306. *
  307. * FUNCTION: acpi_ut_create_list
  308. *
  309. * PARAMETERS: cache_name - Ascii name for the cache
  310. * object_size - Size of each cached object
  311. * return_cache - Where the new cache object is returned
  312. *
  313. * RETURN: Status
  314. *
  315. * DESCRIPTION: Create a local memory list for tracking purposed
  316. *
  317. ******************************************************************************/
  318. static acpi_status
  319. acpi_ut_create_list(char *list_name,
  320. u16 object_size, struct acpi_memory_list **return_cache)
  321. {
  322. struct acpi_memory_list *cache;
  323. cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
  324. if (!cache) {
  325. return (AE_NO_MEMORY);
  326. }
  327. ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
  328. cache->list_name = list_name;
  329. cache->object_size = object_size;
  330. *return_cache = cache;
  331. return (AE_OK);
  332. }
  333. /*******************************************************************************
  334. *
  335. * FUNCTION: acpi_ut_allocate_and_track
  336. *
  337. * PARAMETERS: Size - Size of the allocation
  338. * Component - Component type of caller
  339. * Module - Source file name of caller
  340. * Line - Line number of caller
  341. *
  342. * RETURN: Address of the allocated memory on success, NULL on failure.
  343. *
  344. * DESCRIPTION: The subsystem's equivalent of malloc.
  345. *
  346. ******************************************************************************/
  347. void *acpi_ut_allocate_and_track(acpi_size size,
  348. u32 component, char *module, u32 line)
  349. {
  350. struct acpi_debug_mem_block *allocation;
  351. acpi_status status;
  352. allocation =
  353. acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header),
  354. component, module, line);
  355. if (!allocation) {
  356. return (NULL);
  357. }
  358. status = acpi_ut_track_allocation(allocation, size,
  359. ACPI_MEM_MALLOC, component, module,
  360. line);
  361. if (ACPI_FAILURE(status)) {
  362. acpi_os_free(allocation);
  363. return (NULL);
  364. }
  365. acpi_gbl_global_list->total_allocated++;
  366. acpi_gbl_global_list->current_total_size += (u32) size;
  367. return ((void *)&allocation->user_space);
  368. }
  369. /*******************************************************************************
  370. *
  371. * FUNCTION: acpi_ut_callocate_and_track
  372. *
  373. * PARAMETERS: Size - Size of the allocation
  374. * Component - Component type of caller
  375. * Module - Source file name of caller
  376. * Line - Line number of caller
  377. *
  378. * RETURN: Address of the allocated memory on success, NULL on failure.
  379. *
  380. * DESCRIPTION: Subsystem equivalent of calloc.
  381. *
  382. ******************************************************************************/
  383. void *acpi_ut_callocate_and_track(acpi_size size,
  384. u32 component, char *module, u32 line)
  385. {
  386. struct acpi_debug_mem_block *allocation;
  387. acpi_status status;
  388. allocation =
  389. acpi_ut_callocate(size + sizeof(struct acpi_debug_mem_header),
  390. component, module, line);
  391. if (!allocation) {
  392. /* Report allocation error */
  393. ACPI_ERROR((module, line,
  394. "Could not allocate size %X", (u32) size));
  395. return (NULL);
  396. }
  397. status = acpi_ut_track_allocation(allocation, size,
  398. ACPI_MEM_CALLOC, component, module,
  399. line);
  400. if (ACPI_FAILURE(status)) {
  401. acpi_os_free(allocation);
  402. return (NULL);
  403. }
  404. acpi_gbl_global_list->total_allocated++;
  405. acpi_gbl_global_list->current_total_size += (u32) size;
  406. return ((void *)&allocation->user_space);
  407. }
  408. /*******************************************************************************
  409. *
  410. * FUNCTION: acpi_ut_free_and_track
  411. *
  412. * PARAMETERS: Allocation - Address of the memory to deallocate
  413. * Component - Component type of caller
  414. * Module - Source file name of caller
  415. * Line - Line number of caller
  416. *
  417. * RETURN: None
  418. *
  419. * DESCRIPTION: Frees the memory at Allocation
  420. *
  421. ******************************************************************************/
  422. void
  423. acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line)
  424. {
  425. struct acpi_debug_mem_block *debug_block;
  426. acpi_status status;
  427. ACPI_FUNCTION_TRACE_PTR("ut_free", allocation);
  428. if (NULL == allocation) {
  429. ACPI_ERROR((module, line, "Attempt to delete a NULL address"));
  430. return_VOID;
  431. }
  432. debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
  433. (((char *)allocation) -
  434. sizeof(struct acpi_debug_mem_header)));
  435. acpi_gbl_global_list->total_freed++;
  436. acpi_gbl_global_list->current_total_size -= debug_block->size;
  437. status = acpi_ut_remove_allocation(debug_block,
  438. component, module, line);
  439. if (ACPI_FAILURE(status)) {
  440. ACPI_EXCEPTION((AE_INFO, status, "Could not free memory"));
  441. }
  442. acpi_os_free(debug_block);
  443. ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
  444. return_VOID;
  445. }
  446. /*******************************************************************************
  447. *
  448. * FUNCTION: acpi_ut_find_allocation
  449. *
  450. * PARAMETERS: Allocation - Address of allocated memory
  451. *
  452. * RETURN: A list element if found; NULL otherwise.
  453. *
  454. * DESCRIPTION: Searches for an element in the global allocation tracking list.
  455. *
  456. ******************************************************************************/
  457. static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation)
  458. {
  459. struct acpi_debug_mem_block *element;
  460. ACPI_FUNCTION_ENTRY();
  461. element = acpi_gbl_global_list->list_head;
  462. /* Search for the address. */
  463. while (element) {
  464. if (element == allocation) {
  465. return (element);
  466. }
  467. element = element->next;
  468. }
  469. return (NULL);
  470. }
  471. /*******************************************************************************
  472. *
  473. * FUNCTION: acpi_ut_track_allocation
  474. *
  475. * PARAMETERS: Allocation - Address of allocated memory
  476. * Size - Size of the allocation
  477. * alloc_type - MEM_MALLOC or MEM_CALLOC
  478. * Component - Component type of caller
  479. * Module - Source file name of caller
  480. * Line - Line number of caller
  481. *
  482. * RETURN: None.
  483. *
  484. * DESCRIPTION: Inserts an element into the global allocation tracking list.
  485. *
  486. ******************************************************************************/
  487. static acpi_status
  488. acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
  489. acpi_size size,
  490. u8 alloc_type, u32 component, char *module, u32 line)
  491. {
  492. struct acpi_memory_list *mem_list;
  493. struct acpi_debug_mem_block *element;
  494. acpi_status status = AE_OK;
  495. ACPI_FUNCTION_TRACE_PTR("ut_track_allocation", allocation);
  496. mem_list = acpi_gbl_global_list;
  497. status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  498. if (ACPI_FAILURE(status)) {
  499. return_ACPI_STATUS(status);
  500. }
  501. /*
  502. * Search list for this address to make sure it is not already on the list.
  503. * This will catch several kinds of problems.
  504. */
  505. element = acpi_ut_find_allocation(allocation);
  506. if (element) {
  507. ACPI_ERROR((AE_INFO,
  508. "ut_track_allocation: Allocation already present in list! (%p)",
  509. allocation));
  510. ACPI_ERROR((AE_INFO, "Element %p Address %p",
  511. element, allocation));
  512. goto unlock_and_exit;
  513. }
  514. /* Fill in the instance data. */
  515. allocation->size = (u32) size;
  516. allocation->alloc_type = alloc_type;
  517. allocation->component = component;
  518. allocation->line = line;
  519. ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME);
  520. allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
  521. /* Insert at list head */
  522. if (mem_list->list_head) {
  523. ((struct acpi_debug_mem_block *)(mem_list->list_head))->
  524. previous = allocation;
  525. }
  526. allocation->next = mem_list->list_head;
  527. allocation->previous = NULL;
  528. mem_list->list_head = allocation;
  529. unlock_and_exit:
  530. status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  531. return_ACPI_STATUS(status);
  532. }
  533. /*******************************************************************************
  534. *
  535. * FUNCTION: acpi_ut_remove_allocation
  536. *
  537. * PARAMETERS: Allocation - Address of allocated memory
  538. * Component - Component type of caller
  539. * Module - Source file name of caller
  540. * Line - Line number of caller
  541. *
  542. * RETURN:
  543. *
  544. * DESCRIPTION: Deletes an element from the global allocation tracking list.
  545. *
  546. ******************************************************************************/
  547. static acpi_status
  548. acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
  549. u32 component, char *module, u32 line)
  550. {
  551. struct acpi_memory_list *mem_list;
  552. acpi_status status;
  553. ACPI_FUNCTION_TRACE("ut_remove_allocation");
  554. mem_list = acpi_gbl_global_list;
  555. if (NULL == mem_list->list_head) {
  556. /* No allocations! */
  557. ACPI_ERROR((module, line,
  558. "Empty allocation list, nothing to free!"));
  559. return_ACPI_STATUS(AE_OK);
  560. }
  561. status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  562. if (ACPI_FAILURE(status)) {
  563. return_ACPI_STATUS(status);
  564. }
  565. /* Unlink */
  566. if (allocation->previous) {
  567. (allocation->previous)->next = allocation->next;
  568. } else {
  569. mem_list->list_head = allocation->next;
  570. }
  571. if (allocation->next) {
  572. (allocation->next)->previous = allocation->previous;
  573. }
  574. /* Mark the segment as deleted */
  575. ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size);
  576. ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
  577. allocation->size));
  578. status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  579. return_ACPI_STATUS(status);
  580. }
  581. /*******************************************************************************
  582. *
  583. * FUNCTION: acpi_ut_dump_allocation_info
  584. *
  585. * PARAMETERS:
  586. *
  587. * RETURN: None
  588. *
  589. * DESCRIPTION: Print some info about the outstanding allocations.
  590. *
  591. ******************************************************************************/
  592. #ifdef ACPI_FUTURE_USAGE
  593. void acpi_ut_dump_allocation_info(void)
  594. {
  595. /*
  596. struct acpi_memory_list *mem_list;
  597. */
  598. ACPI_FUNCTION_TRACE("ut_dump_allocation_info");
  599. /*
  600. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  601. ("%30s: %4d (%3d Kb)\n", "Current allocations",
  602. mem_list->current_count,
  603. ROUND_UP_TO_1K (mem_list->current_size)));
  604. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  605. ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
  606. mem_list->max_concurrent_count,
  607. ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
  608. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  609. ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
  610. running_object_count,
  611. ROUND_UP_TO_1K (running_object_size)));
  612. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  613. ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
  614. running_alloc_count,
  615. ROUND_UP_TO_1K (running_alloc_size)));
  616. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  617. ("%30s: %4d (%3d Kb)\n", "Current Nodes",
  618. acpi_gbl_current_node_count,
  619. ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
  620. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  621. ("%30s: %4d (%3d Kb)\n", "Max Nodes",
  622. acpi_gbl_max_concurrent_node_count,
  623. ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
  624. sizeof (struct acpi_namespace_node)))));
  625. */
  626. return_VOID;
  627. }
  628. #endif /* ACPI_FUTURE_USAGE */
  629. /*******************************************************************************
  630. *
  631. * FUNCTION: acpi_ut_dump_allocations
  632. *
  633. * PARAMETERS: Component - Component(s) to dump info for.
  634. * Module - Module to dump info for. NULL means all.
  635. *
  636. * RETURN: None
  637. *
  638. * DESCRIPTION: Print a list of all outstanding allocations.
  639. *
  640. ******************************************************************************/
  641. void acpi_ut_dump_allocations(u32 component, char *module)
  642. {
  643. struct acpi_debug_mem_block *element;
  644. union acpi_descriptor *descriptor;
  645. u32 num_outstanding = 0;
  646. ACPI_FUNCTION_TRACE("ut_dump_allocations");
  647. /*
  648. * Walk the allocation list.
  649. */
  650. if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
  651. return;
  652. }
  653. element = acpi_gbl_global_list->list_head;
  654. while (element) {
  655. if ((element->component & component) &&
  656. ((module == NULL)
  657. || (0 == ACPI_STRCMP(module, element->module)))) {
  658. /* Ignore allocated objects that are in a cache */
  659. descriptor =
  660. ACPI_CAST_PTR(union acpi_descriptor,
  661. &element->user_space);
  662. if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
  663. acpi_os_printf("%p Len %04X %9.9s-%d [%s] ",
  664. descriptor, element->size,
  665. element->module, element->line,
  666. acpi_ut_get_descriptor_name
  667. (descriptor));
  668. /* Most of the elements will be Operand objects. */
  669. switch (ACPI_GET_DESCRIPTOR_TYPE(descriptor)) {
  670. case ACPI_DESC_TYPE_OPERAND:
  671. acpi_os_printf("%12.12s R%hd",
  672. acpi_ut_get_type_name
  673. (descriptor->object.
  674. common.type),
  675. descriptor->object.
  676. common.reference_count);
  677. break;
  678. case ACPI_DESC_TYPE_PARSER:
  679. acpi_os_printf("aml_opcode %04hX",
  680. descriptor->op.asl.
  681. aml_opcode);
  682. break;
  683. case ACPI_DESC_TYPE_NAMED:
  684. acpi_os_printf("%4.4s",
  685. acpi_ut_get_node_name
  686. (&descriptor->node));
  687. break;
  688. default:
  689. break;
  690. }
  691. acpi_os_printf("\n");
  692. num_outstanding++;
  693. }
  694. }
  695. element = element->next;
  696. }
  697. (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  698. /* Print summary */
  699. if (!num_outstanding) {
  700. ACPI_INFO((AE_INFO, "No outstanding allocations"));
  701. } else {
  702. ACPI_ERROR((AE_INFO,
  703. "%d(%X) Outstanding allocations",
  704. num_outstanding, num_outstanding));
  705. }
  706. return_VOID;
  707. }
  708. #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */