utalloc.c 24 KB

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