utalloc.c 27 KB

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