utalloc.c 27 KB

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