utalloc.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  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_REPORT_ERROR(module, line,
  246. ("ut_allocate: Attempt to allocate zero bytes, allocating 1 byte\n"));
  247. size = 1;
  248. }
  249. allocation = acpi_os_allocate(size);
  250. if (!allocation) {
  251. /* Report allocation error */
  252. _ACPI_REPORT_ERROR(module, line,
  253. ("ut_allocate: Could not allocate size %X\n",
  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_REPORT_ERROR(module, line,
  280. ("ut_callocate: Attempt to allocate zero bytes, allocating 1 byte\n"));
  281. size = 1;
  282. }
  283. allocation = acpi_os_allocate(size);
  284. if (!allocation) {
  285. /* Report allocation error */
  286. _ACPI_REPORT_ERROR(module, line,
  287. ("ut_callocate: Could not allocate size %X\n",
  288. (u32) size));
  289. return_PTR(NULL);
  290. }
  291. /* Clear the memory block */
  292. ACPI_MEMSET(allocation, 0, size);
  293. return_PTR(allocation);
  294. }
  295. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  296. /*
  297. * These procedures are used for tracking memory leaks in the subsystem, and
  298. * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
  299. *
  300. * Each memory allocation is tracked via a doubly linked list. Each
  301. * element contains the caller's component, module name, function name, and
  302. * line number. acpi_ut_allocate and acpi_ut_callocate call
  303. * acpi_ut_track_allocation to add an element to the list; deletion
  304. * occurs in the body of acpi_ut_free.
  305. */
  306. /*******************************************************************************
  307. *
  308. * FUNCTION: acpi_ut_create_list
  309. *
  310. * PARAMETERS: cache_name - Ascii name for the cache
  311. * object_size - Size of each cached object
  312. * return_cache - Where the new cache object is returned
  313. *
  314. * RETURN: Status
  315. *
  316. * DESCRIPTION: Create a local memory list for tracking purposed
  317. *
  318. ******************************************************************************/
  319. static acpi_status
  320. acpi_ut_create_list(char *list_name,
  321. u16 object_size, struct acpi_memory_list **return_cache)
  322. {
  323. struct acpi_memory_list *cache;
  324. cache = acpi_os_allocate(sizeof(struct acpi_memory_list));
  325. if (!cache) {
  326. return (AE_NO_MEMORY);
  327. }
  328. ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list));
  329. cache->list_name = list_name;
  330. cache->object_size = object_size;
  331. *return_cache = cache;
  332. return (AE_OK);
  333. }
  334. /*******************************************************************************
  335. *
  336. * FUNCTION: acpi_ut_allocate_and_track
  337. *
  338. * PARAMETERS: Size - Size of the allocation
  339. * Component - Component type of caller
  340. * Module - Source file name of caller
  341. * Line - Line number of caller
  342. *
  343. * RETURN: Address of the allocated memory on success, NULL on failure.
  344. *
  345. * DESCRIPTION: The subsystem's equivalent of malloc.
  346. *
  347. ******************************************************************************/
  348. void *acpi_ut_allocate_and_track(acpi_size size,
  349. u32 component, char *module, u32 line)
  350. {
  351. struct acpi_debug_mem_block *allocation;
  352. acpi_status status;
  353. allocation =
  354. acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header),
  355. component, module, line);
  356. if (!allocation) {
  357. return (NULL);
  358. }
  359. status = acpi_ut_track_allocation(allocation, size,
  360. ACPI_MEM_MALLOC, component, module,
  361. line);
  362. if (ACPI_FAILURE(status)) {
  363. acpi_os_free(allocation);
  364. return (NULL);
  365. }
  366. acpi_gbl_global_list->total_allocated++;
  367. acpi_gbl_global_list->current_total_size += (u32) size;
  368. return ((void *)&allocation->user_space);
  369. }
  370. /*******************************************************************************
  371. *
  372. * FUNCTION: acpi_ut_callocate_and_track
  373. *
  374. * PARAMETERS: Size - Size of the allocation
  375. * Component - Component type of caller
  376. * Module - Source file name of caller
  377. * Line - Line number of caller
  378. *
  379. * RETURN: Address of the allocated memory on success, NULL on failure.
  380. *
  381. * DESCRIPTION: Subsystem equivalent of calloc.
  382. *
  383. ******************************************************************************/
  384. void *acpi_ut_callocate_and_track(acpi_size size,
  385. u32 component, char *module, u32 line)
  386. {
  387. struct acpi_debug_mem_block *allocation;
  388. acpi_status status;
  389. allocation =
  390. acpi_ut_callocate(size + sizeof(struct acpi_debug_mem_header),
  391. component, module, line);
  392. if (!allocation) {
  393. /* Report allocation error */
  394. _ACPI_REPORT_ERROR(module, line,
  395. ("ut_callocate: Could not allocate size %X\n",
  396. (u32) size));
  397. return (NULL);
  398. }
  399. status = acpi_ut_track_allocation(allocation, size,
  400. ACPI_MEM_CALLOC, component, module,
  401. line);
  402. if (ACPI_FAILURE(status)) {
  403. acpi_os_free(allocation);
  404. return (NULL);
  405. }
  406. acpi_gbl_global_list->total_allocated++;
  407. acpi_gbl_global_list->current_total_size += (u32) size;
  408. return ((void *)&allocation->user_space);
  409. }
  410. /*******************************************************************************
  411. *
  412. * FUNCTION: acpi_ut_free_and_track
  413. *
  414. * PARAMETERS: Allocation - Address of the memory to deallocate
  415. * Component - Component type of caller
  416. * Module - Source file name of caller
  417. * Line - Line number of caller
  418. *
  419. * RETURN: None
  420. *
  421. * DESCRIPTION: Frees the memory at Allocation
  422. *
  423. ******************************************************************************/
  424. void
  425. acpi_ut_free_and_track(void *allocation, u32 component, char *module, u32 line)
  426. {
  427. struct acpi_debug_mem_block *debug_block;
  428. acpi_status status;
  429. ACPI_FUNCTION_TRACE_PTR("ut_free", allocation);
  430. if (NULL == allocation) {
  431. _ACPI_REPORT_ERROR(module, line,
  432. ("acpi_ut_free: Attempt to delete a NULL address\n"));
  433. return_VOID;
  434. }
  435. debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block,
  436. (((char *)allocation) -
  437. sizeof(struct acpi_debug_mem_header)));
  438. acpi_gbl_global_list->total_freed++;
  439. acpi_gbl_global_list->current_total_size -= debug_block->size;
  440. status = acpi_ut_remove_allocation(debug_block,
  441. component, module, line);
  442. if (ACPI_FAILURE(status)) {
  443. ACPI_REPORT_ERROR(("Could not free memory, %s\n",
  444. acpi_format_exception(status)));
  445. }
  446. acpi_os_free(debug_block);
  447. ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation));
  448. return_VOID;
  449. }
  450. /*******************************************************************************
  451. *
  452. * FUNCTION: acpi_ut_find_allocation
  453. *
  454. * PARAMETERS: Allocation - Address of allocated memory
  455. *
  456. * RETURN: A list element if found; NULL otherwise.
  457. *
  458. * DESCRIPTION: Searches for an element in the global allocation tracking list.
  459. *
  460. ******************************************************************************/
  461. static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation)
  462. {
  463. struct acpi_debug_mem_block *element;
  464. ACPI_FUNCTION_ENTRY();
  465. element = acpi_gbl_global_list->list_head;
  466. /* Search for the address. */
  467. while (element) {
  468. if (element == allocation) {
  469. return (element);
  470. }
  471. element = element->next;
  472. }
  473. return (NULL);
  474. }
  475. /*******************************************************************************
  476. *
  477. * FUNCTION: acpi_ut_track_allocation
  478. *
  479. * PARAMETERS: Allocation - Address of allocated memory
  480. * Size - Size of the allocation
  481. * alloc_type - MEM_MALLOC or MEM_CALLOC
  482. * Component - Component type of caller
  483. * Module - Source file name of caller
  484. * Line - Line number of caller
  485. *
  486. * RETURN: None.
  487. *
  488. * DESCRIPTION: Inserts an element into the global allocation tracking list.
  489. *
  490. ******************************************************************************/
  491. static acpi_status
  492. acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation,
  493. acpi_size size,
  494. u8 alloc_type, u32 component, char *module, u32 line)
  495. {
  496. struct acpi_memory_list *mem_list;
  497. struct acpi_debug_mem_block *element;
  498. acpi_status status = AE_OK;
  499. ACPI_FUNCTION_TRACE_PTR("ut_track_allocation", allocation);
  500. mem_list = acpi_gbl_global_list;
  501. status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  502. if (ACPI_FAILURE(status)) {
  503. return_ACPI_STATUS(status);
  504. }
  505. /*
  506. * Search list for this address to make sure it is not already on the list.
  507. * This will catch several kinds of problems.
  508. */
  509. element = acpi_ut_find_allocation(allocation);
  510. if (element) {
  511. ACPI_REPORT_ERROR(("ut_track_allocation: Allocation already present in list! (%p)\n", allocation));
  512. ACPI_REPORT_ERROR(("Element %p Address %p\n",
  513. element, allocation));
  514. goto unlock_and_exit;
  515. }
  516. /* Fill in the instance data. */
  517. allocation->size = (u32) size;
  518. allocation->alloc_type = alloc_type;
  519. allocation->component = component;
  520. allocation->line = line;
  521. ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME);
  522. allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0;
  523. /* Insert at list head */
  524. if (mem_list->list_head) {
  525. ((struct acpi_debug_mem_block *)(mem_list->list_head))->
  526. previous = allocation;
  527. }
  528. allocation->next = mem_list->list_head;
  529. allocation->previous = NULL;
  530. mem_list->list_head = allocation;
  531. unlock_and_exit:
  532. status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  533. return_ACPI_STATUS(status);
  534. }
  535. /*******************************************************************************
  536. *
  537. * FUNCTION: acpi_ut_remove_allocation
  538. *
  539. * PARAMETERS: Allocation - Address of allocated memory
  540. * Component - Component type of caller
  541. * Module - Source file name of caller
  542. * Line - Line number of caller
  543. *
  544. * RETURN:
  545. *
  546. * DESCRIPTION: Deletes an element from the global allocation tracking list.
  547. *
  548. ******************************************************************************/
  549. static acpi_status
  550. acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation,
  551. u32 component, char *module, u32 line)
  552. {
  553. struct acpi_memory_list *mem_list;
  554. acpi_status status;
  555. ACPI_FUNCTION_TRACE("ut_remove_allocation");
  556. mem_list = acpi_gbl_global_list;
  557. if (NULL == mem_list->list_head) {
  558. /* No allocations! */
  559. _ACPI_REPORT_ERROR(module, line,
  560. ("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
  561. return_ACPI_STATUS(AE_OK);
  562. }
  563. status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY);
  564. if (ACPI_FAILURE(status)) {
  565. return_ACPI_STATUS(status);
  566. }
  567. /* Unlink */
  568. if (allocation->previous) {
  569. (allocation->previous)->next = allocation->next;
  570. } else {
  571. mem_list->list_head = allocation->next;
  572. }
  573. if (allocation->next) {
  574. (allocation->next)->previous = allocation->previous;
  575. }
  576. /* Mark the segment as deleted */
  577. ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size);
  578. ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
  579. allocation->size));
  580. status = acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  581. return_ACPI_STATUS(status);
  582. }
  583. /*******************************************************************************
  584. *
  585. * FUNCTION: acpi_ut_dump_allocation_info
  586. *
  587. * PARAMETERS:
  588. *
  589. * RETURN: None
  590. *
  591. * DESCRIPTION: Print some info about the outstanding allocations.
  592. *
  593. ******************************************************************************/
  594. #ifdef ACPI_FUTURE_USAGE
  595. void acpi_ut_dump_allocation_info(void)
  596. {
  597. /*
  598. struct acpi_memory_list *mem_list;
  599. */
  600. ACPI_FUNCTION_TRACE("ut_dump_allocation_info");
  601. /*
  602. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  603. ("%30s: %4d (%3d Kb)\n", "Current allocations",
  604. mem_list->current_count,
  605. ROUND_UP_TO_1K (mem_list->current_size)));
  606. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  607. ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
  608. mem_list->max_concurrent_count,
  609. ROUND_UP_TO_1K (mem_list->max_concurrent_size)));
  610. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  611. ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
  612. running_object_count,
  613. ROUND_UP_TO_1K (running_object_size)));
  614. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  615. ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
  616. running_alloc_count,
  617. ROUND_UP_TO_1K (running_alloc_size)));
  618. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  619. ("%30s: %4d (%3d Kb)\n", "Current Nodes",
  620. acpi_gbl_current_node_count,
  621. ROUND_UP_TO_1K (acpi_gbl_current_node_size)));
  622. ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
  623. ("%30s: %4d (%3d Kb)\n", "Max Nodes",
  624. acpi_gbl_max_concurrent_node_count,
  625. ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
  626. sizeof (struct acpi_namespace_node)))));
  627. */
  628. return_VOID;
  629. }
  630. #endif /* ACPI_FUTURE_USAGE */
  631. /*******************************************************************************
  632. *
  633. * FUNCTION: acpi_ut_dump_allocations
  634. *
  635. * PARAMETERS: Component - Component(s) to dump info for.
  636. * Module - Module to dump info for. NULL means all.
  637. *
  638. * RETURN: None
  639. *
  640. * DESCRIPTION: Print a list of all outstanding allocations.
  641. *
  642. ******************************************************************************/
  643. void acpi_ut_dump_allocations(u32 component, char *module)
  644. {
  645. struct acpi_debug_mem_block *element;
  646. union acpi_descriptor *descriptor;
  647. u32 num_outstanding = 0;
  648. ACPI_FUNCTION_TRACE("ut_dump_allocations");
  649. /*
  650. * Walk the allocation list.
  651. */
  652. if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) {
  653. return;
  654. }
  655. element = acpi_gbl_global_list->list_head;
  656. while (element) {
  657. if ((element->component & component) &&
  658. ((module == NULL)
  659. || (0 == ACPI_STRCMP(module, element->module)))) {
  660. /* Ignore allocated objects that are in a cache */
  661. descriptor =
  662. ACPI_CAST_PTR(union acpi_descriptor,
  663. &element->user_space);
  664. if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
  665. acpi_os_printf("%p Len %04X %9.9s-%d [%s] ",
  666. descriptor, element->size,
  667. element->module, element->line,
  668. acpi_ut_get_descriptor_name
  669. (descriptor));
  670. /* Most of the elements will be Operand objects. */
  671. switch (ACPI_GET_DESCRIPTOR_TYPE(descriptor)) {
  672. case ACPI_DESC_TYPE_OPERAND:
  673. acpi_os_printf("%12.12s R%hd",
  674. acpi_ut_get_type_name
  675. (descriptor->object.
  676. common.type),
  677. descriptor->object.
  678. common.reference_count);
  679. break;
  680. case ACPI_DESC_TYPE_PARSER:
  681. acpi_os_printf("aml_opcode %04hX",
  682. descriptor->op.asl.
  683. aml_opcode);
  684. break;
  685. case ACPI_DESC_TYPE_NAMED:
  686. acpi_os_printf("%4.4s",
  687. acpi_ut_get_node_name
  688. (&descriptor->node));
  689. break;
  690. default:
  691. break;
  692. }
  693. acpi_os_printf("\n");
  694. num_outstanding++;
  695. }
  696. }
  697. element = element->next;
  698. }
  699. (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
  700. /* Print summary */
  701. if (!num_outstanding) {
  702. ACPI_REPORT_INFO(("No outstanding allocations\n"));
  703. } else {
  704. ACPI_REPORT_ERROR(("%d(%X) Outstanding allocations\n",
  705. num_outstanding, num_outstanding));
  706. }
  707. return_VOID;
  708. }
  709. #endif /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */