dbstats.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. /*******************************************************************************
  2. *
  3. * Module Name: dbstats - Generation and display of ACPI table statistics
  4. *
  5. ******************************************************************************/
  6. /*
  7. * Copyright (C) 2000 - 2015, Intel Corp.
  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. #include "accommon.h"
  44. #include "acdebug.h"
  45. #include "acnamesp.h"
  46. #define _COMPONENT ACPI_CA_DEBUGGER
  47. ACPI_MODULE_NAME("dbstats")
  48. /* Local prototypes */
  49. static void acpi_db_count_namespace_objects(void);
  50. static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc);
  51. static acpi_status
  52. acpi_db_classify_one_object(acpi_handle obj_handle,
  53. u32 nesting_level,
  54. void *context, void **return_value);
  55. #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
  56. static void acpi_db_list_info(struct acpi_memory_list *list);
  57. #endif
  58. /*
  59. * Statistics subcommands
  60. */
  61. static struct acpi_db_argument_info acpi_db_stat_types[] = {
  62. {"ALLOCATIONS"},
  63. {"OBJECTS"},
  64. {"MEMORY"},
  65. {"MISC"},
  66. {"TABLES"},
  67. {"SIZES"},
  68. {"STACK"},
  69. {NULL} /* Must be null terminated */
  70. };
  71. #define CMD_STAT_ALLOCATIONS 0
  72. #define CMD_STAT_OBJECTS 1
  73. #define CMD_STAT_MEMORY 2
  74. #define CMD_STAT_MISC 3
  75. #define CMD_STAT_TABLES 4
  76. #define CMD_STAT_SIZES 5
  77. #define CMD_STAT_STACK 6
  78. #if defined ACPI_DBG_TRACK_ALLOCATIONS || defined ACPI_USE_LOCAL_CACHE
  79. /*******************************************************************************
  80. *
  81. * FUNCTION: acpi_db_list_info
  82. *
  83. * PARAMETERS: list - Memory list/cache to be displayed
  84. *
  85. * RETURN: None
  86. *
  87. * DESCRIPTION: Display information about the input memory list or cache.
  88. *
  89. ******************************************************************************/
  90. static void acpi_db_list_info(struct acpi_memory_list *list)
  91. {
  92. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  93. u32 outstanding;
  94. #endif
  95. acpi_os_printf("\n%s\n", list->list_name);
  96. /* max_depth > 0 indicates a cache object */
  97. if (list->max_depth > 0) {
  98. acpi_os_printf
  99. (" Cache: [Depth MaxD Avail Size] "
  100. "%8.2X %8.2X %8.2X %8.2X\n", list->current_depth,
  101. list->max_depth, list->max_depth - list->current_depth,
  102. (list->current_depth * list->object_size));
  103. }
  104. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  105. if (list->max_depth > 0) {
  106. acpi_os_printf
  107. (" Cache: [Requests Hits Misses ObjSize] "
  108. "%8.2X %8.2X %8.2X %8.2X\n", list->requests, list->hits,
  109. list->requests - list->hits, list->object_size);
  110. }
  111. outstanding = acpi_db_get_cache_info(list);
  112. if (list->object_size) {
  113. acpi_os_printf
  114. (" Mem: [Alloc Free Max CurSize Outstanding] "
  115. "%8.2X %8.2X %8.2X %8.2X %8.2X\n", list->total_allocated,
  116. list->total_freed, list->max_occupied,
  117. outstanding * list->object_size, outstanding);
  118. } else {
  119. acpi_os_printf
  120. (" Mem: [Alloc Free Max CurSize Outstanding Total] "
  121. "%8.2X %8.2X %8.2X %8.2X %8.2X %8.2X\n",
  122. list->total_allocated, list->total_freed,
  123. list->max_occupied, list->current_total_size, outstanding,
  124. list->total_size);
  125. }
  126. #endif
  127. }
  128. #endif
  129. /*******************************************************************************
  130. *
  131. * FUNCTION: acpi_db_enumerate_object
  132. *
  133. * PARAMETERS: obj_desc - Object to be counted
  134. *
  135. * RETURN: None
  136. *
  137. * DESCRIPTION: Add this object to the global counts, by object type.
  138. * Limited recursion handles subobjects and packages, and this
  139. * is probably acceptable within the AML debugger only.
  140. *
  141. ******************************************************************************/
  142. static void acpi_db_enumerate_object(union acpi_operand_object *obj_desc)
  143. {
  144. u32 i;
  145. if (!obj_desc) {
  146. return;
  147. }
  148. /* Enumerate this object first */
  149. acpi_gbl_num_objects++;
  150. if (obj_desc->common.type > ACPI_TYPE_NS_NODE_MAX) {
  151. acpi_gbl_obj_type_count_misc++;
  152. } else {
  153. acpi_gbl_obj_type_count[obj_desc->common.type]++;
  154. }
  155. /* Count the sub-objects */
  156. switch (obj_desc->common.type) {
  157. case ACPI_TYPE_PACKAGE:
  158. for (i = 0; i < obj_desc->package.count; i++) {
  159. acpi_db_enumerate_object(obj_desc->package.elements[i]);
  160. }
  161. break;
  162. case ACPI_TYPE_DEVICE:
  163. acpi_db_enumerate_object(obj_desc->device.notify_list[0]);
  164. acpi_db_enumerate_object(obj_desc->device.notify_list[1]);
  165. acpi_db_enumerate_object(obj_desc->device.handler);
  166. break;
  167. case ACPI_TYPE_BUFFER_FIELD:
  168. if (acpi_ns_get_secondary_object(obj_desc)) {
  169. acpi_gbl_obj_type_count[ACPI_TYPE_BUFFER_FIELD]++;
  170. }
  171. break;
  172. case ACPI_TYPE_REGION:
  173. acpi_gbl_obj_type_count[ACPI_TYPE_LOCAL_REGION_FIELD]++;
  174. acpi_db_enumerate_object(obj_desc->region.handler);
  175. break;
  176. case ACPI_TYPE_POWER:
  177. acpi_db_enumerate_object(obj_desc->power_resource.
  178. notify_list[0]);
  179. acpi_db_enumerate_object(obj_desc->power_resource.
  180. notify_list[1]);
  181. break;
  182. case ACPI_TYPE_PROCESSOR:
  183. acpi_db_enumerate_object(obj_desc->processor.notify_list[0]);
  184. acpi_db_enumerate_object(obj_desc->processor.notify_list[1]);
  185. acpi_db_enumerate_object(obj_desc->processor.handler);
  186. break;
  187. case ACPI_TYPE_THERMAL:
  188. acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[0]);
  189. acpi_db_enumerate_object(obj_desc->thermal_zone.notify_list[1]);
  190. acpi_db_enumerate_object(obj_desc->thermal_zone.handler);
  191. break;
  192. default:
  193. break;
  194. }
  195. }
  196. /*******************************************************************************
  197. *
  198. * FUNCTION: acpi_db_classify_one_object
  199. *
  200. * PARAMETERS: Callback for walk_namespace
  201. *
  202. * RETURN: Status
  203. *
  204. * DESCRIPTION: Enumerate both the object descriptor (including subobjects) and
  205. * the parent namespace node.
  206. *
  207. ******************************************************************************/
  208. static acpi_status
  209. acpi_db_classify_one_object(acpi_handle obj_handle,
  210. u32 nesting_level,
  211. void *context, void **return_value)
  212. {
  213. struct acpi_namespace_node *node;
  214. union acpi_operand_object *obj_desc;
  215. u32 type;
  216. acpi_gbl_num_nodes++;
  217. node = (struct acpi_namespace_node *)obj_handle;
  218. obj_desc = acpi_ns_get_attached_object(node);
  219. acpi_db_enumerate_object(obj_desc);
  220. type = node->type;
  221. if (type > ACPI_TYPE_NS_NODE_MAX) {
  222. acpi_gbl_node_type_count_misc++;
  223. } else {
  224. acpi_gbl_node_type_count[type]++;
  225. }
  226. return (AE_OK);
  227. #ifdef ACPI_FUTURE_IMPLEMENTATION
  228. /* TBD: These need to be counted during the initial parsing phase */
  229. if (acpi_ps_is_named_op(op->opcode)) {
  230. num_nodes++;
  231. }
  232. if (is_method) {
  233. num_method_elements++;
  234. }
  235. num_grammar_elements++;
  236. op = acpi_ps_get_depth_next(root, op);
  237. size_of_parse_tree = (num_grammar_elements - num_method_elements) *
  238. (u32)sizeof(union acpi_parse_object);
  239. size_of_method_trees =
  240. num_method_elements * (u32)sizeof(union acpi_parse_object);
  241. size_of_node_entries =
  242. num_nodes * (u32)sizeof(struct acpi_namespace_node);
  243. size_of_acpi_objects =
  244. num_nodes * (u32)sizeof(union acpi_operand_object);
  245. #endif
  246. }
  247. /*******************************************************************************
  248. *
  249. * FUNCTION: acpi_db_count_namespace_objects
  250. *
  251. * PARAMETERS: None
  252. *
  253. * RETURN: None
  254. *
  255. * DESCRIPTION: Count and classify the entire namespace, including all
  256. * namespace nodes and attached objects.
  257. *
  258. ******************************************************************************/
  259. static void acpi_db_count_namespace_objects(void)
  260. {
  261. u32 i;
  262. acpi_gbl_num_nodes = 0;
  263. acpi_gbl_num_objects = 0;
  264. acpi_gbl_obj_type_count_misc = 0;
  265. for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX - 1); i++) {
  266. acpi_gbl_obj_type_count[i] = 0;
  267. acpi_gbl_node_type_count[i] = 0;
  268. }
  269. (void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
  270. ACPI_UINT32_MAX, FALSE,
  271. acpi_db_classify_one_object, NULL, NULL,
  272. NULL);
  273. }
  274. /*******************************************************************************
  275. *
  276. * FUNCTION: acpi_db_display_statistics
  277. *
  278. * PARAMETERS: type_arg - Subcommand
  279. *
  280. * RETURN: Status
  281. *
  282. * DESCRIPTION: Display various statistics
  283. *
  284. ******************************************************************************/
  285. acpi_status acpi_db_display_statistics(char *type_arg)
  286. {
  287. u32 i;
  288. u32 temp;
  289. acpi_ut_strupr(type_arg);
  290. temp = acpi_db_match_argument(type_arg, acpi_db_stat_types);
  291. if (temp == ACPI_TYPE_NOT_FOUND) {
  292. acpi_os_printf("Invalid or unsupported argument\n");
  293. return (AE_OK);
  294. }
  295. switch (temp) {
  296. case CMD_STAT_ALLOCATIONS:
  297. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  298. acpi_ut_dump_allocation_info();
  299. #endif
  300. break;
  301. case CMD_STAT_TABLES:
  302. acpi_os_printf("ACPI Table Information (not implemented):\n\n");
  303. break;
  304. case CMD_STAT_OBJECTS:
  305. acpi_db_count_namespace_objects();
  306. acpi_os_printf
  307. ("\nObjects defined in the current namespace:\n\n");
  308. acpi_os_printf("%16.16s %10.10s %10.10s\n",
  309. "ACPI_TYPE", "NODES", "OBJECTS");
  310. for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
  311. acpi_os_printf("%16.16s % 10ld% 10ld\n",
  312. acpi_ut_get_type_name(i),
  313. acpi_gbl_node_type_count[i],
  314. acpi_gbl_obj_type_count[i]);
  315. }
  316. acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
  317. acpi_gbl_node_type_count_misc,
  318. acpi_gbl_obj_type_count_misc);
  319. acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:",
  320. acpi_gbl_num_nodes, acpi_gbl_num_objects);
  321. break;
  322. case CMD_STAT_MEMORY:
  323. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  324. acpi_os_printf
  325. ("\n----Object Statistics (all in hex)---------\n");
  326. acpi_db_list_info(acpi_gbl_global_list);
  327. acpi_db_list_info(acpi_gbl_ns_node_list);
  328. #endif
  329. #ifdef ACPI_USE_LOCAL_CACHE
  330. acpi_os_printf
  331. ("\n----Cache Statistics (all in hex)---------\n");
  332. acpi_db_list_info(acpi_gbl_operand_cache);
  333. acpi_db_list_info(acpi_gbl_ps_node_cache);
  334. acpi_db_list_info(acpi_gbl_ps_node_ext_cache);
  335. acpi_db_list_info(acpi_gbl_state_cache);
  336. #endif
  337. break;
  338. case CMD_STAT_MISC:
  339. acpi_os_printf("\nMiscellaneous Statistics:\n\n");
  340. acpi_os_printf("Calls to AcpiPsFind:.. ........% 7ld\n",
  341. acpi_gbl_ps_find_count);
  342. acpi_os_printf("Calls to AcpiNsLookup:..........% 7ld\n",
  343. acpi_gbl_ns_lookup_count);
  344. acpi_os_printf("\n");
  345. acpi_os_printf("Mutex usage:\n\n");
  346. for (i = 0; i < ACPI_NUM_MUTEX; i++) {
  347. acpi_os_printf("%-28s: % 7ld\n",
  348. acpi_ut_get_mutex_name(i),
  349. acpi_gbl_mutex_info[i].use_count);
  350. }
  351. break;
  352. case CMD_STAT_SIZES:
  353. acpi_os_printf("\nInternal object sizes:\n\n");
  354. acpi_os_printf("Common %3d\n",
  355. sizeof(struct acpi_object_common));
  356. acpi_os_printf("Number %3d\n",
  357. sizeof(struct acpi_object_integer));
  358. acpi_os_printf("String %3d\n",
  359. sizeof(struct acpi_object_string));
  360. acpi_os_printf("Buffer %3d\n",
  361. sizeof(struct acpi_object_buffer));
  362. acpi_os_printf("Package %3d\n",
  363. sizeof(struct acpi_object_package));
  364. acpi_os_printf("BufferField %3d\n",
  365. sizeof(struct acpi_object_buffer_field));
  366. acpi_os_printf("Device %3d\n",
  367. sizeof(struct acpi_object_device));
  368. acpi_os_printf("Event %3d\n",
  369. sizeof(struct acpi_object_event));
  370. acpi_os_printf("Method %3d\n",
  371. sizeof(struct acpi_object_method));
  372. acpi_os_printf("Mutex %3d\n",
  373. sizeof(struct acpi_object_mutex));
  374. acpi_os_printf("Region %3d\n",
  375. sizeof(struct acpi_object_region));
  376. acpi_os_printf("PowerResource %3d\n",
  377. sizeof(struct acpi_object_power_resource));
  378. acpi_os_printf("Processor %3d\n",
  379. sizeof(struct acpi_object_processor));
  380. acpi_os_printf("ThermalZone %3d\n",
  381. sizeof(struct acpi_object_thermal_zone));
  382. acpi_os_printf("RegionField %3d\n",
  383. sizeof(struct acpi_object_region_field));
  384. acpi_os_printf("BankField %3d\n",
  385. sizeof(struct acpi_object_bank_field));
  386. acpi_os_printf("IndexField %3d\n",
  387. sizeof(struct acpi_object_index_field));
  388. acpi_os_printf("Reference %3d\n",
  389. sizeof(struct acpi_object_reference));
  390. acpi_os_printf("Notify %3d\n",
  391. sizeof(struct acpi_object_notify_handler));
  392. acpi_os_printf("AddressSpace %3d\n",
  393. sizeof(struct acpi_object_addr_handler));
  394. acpi_os_printf("Extra %3d\n",
  395. sizeof(struct acpi_object_extra));
  396. acpi_os_printf("Data %3d\n",
  397. sizeof(struct acpi_object_data));
  398. acpi_os_printf("\n");
  399. acpi_os_printf("ParseObject %3d\n",
  400. sizeof(struct acpi_parse_obj_common));
  401. acpi_os_printf("ParseObjectNamed %3d\n",
  402. sizeof(struct acpi_parse_obj_named));
  403. acpi_os_printf("ParseObjectAsl %3d\n",
  404. sizeof(struct acpi_parse_obj_asl));
  405. acpi_os_printf("OperandObject %3d\n",
  406. sizeof(union acpi_operand_object));
  407. acpi_os_printf("NamespaceNode %3d\n",
  408. sizeof(struct acpi_namespace_node));
  409. acpi_os_printf("AcpiObject %3d\n",
  410. sizeof(union acpi_object));
  411. acpi_os_printf("\n");
  412. acpi_os_printf("Generic State %3d\n",
  413. sizeof(union acpi_generic_state));
  414. acpi_os_printf("Common State %3d\n",
  415. sizeof(struct acpi_common_state));
  416. acpi_os_printf("Control State %3d\n",
  417. sizeof(struct acpi_control_state));
  418. acpi_os_printf("Update State %3d\n",
  419. sizeof(struct acpi_update_state));
  420. acpi_os_printf("Scope State %3d\n",
  421. sizeof(struct acpi_scope_state));
  422. acpi_os_printf("Parse Scope %3d\n",
  423. sizeof(struct acpi_pscope_state));
  424. acpi_os_printf("Package State %3d\n",
  425. sizeof(struct acpi_pkg_state));
  426. acpi_os_printf("Thread State %3d\n",
  427. sizeof(struct acpi_thread_state));
  428. acpi_os_printf("Result Values %3d\n",
  429. sizeof(struct acpi_result_values));
  430. acpi_os_printf("Notify Info %3d\n",
  431. sizeof(struct acpi_notify_info));
  432. break;
  433. case CMD_STAT_STACK:
  434. #if defined(ACPI_DEBUG_OUTPUT)
  435. temp =
  436. (u32)ACPI_PTR_DIFF(acpi_gbl_entry_stack_pointer,
  437. acpi_gbl_lowest_stack_pointer);
  438. acpi_os_printf("\nSubsystem Stack Usage:\n\n");
  439. acpi_os_printf("Entry Stack Pointer %p\n",
  440. acpi_gbl_entry_stack_pointer);
  441. acpi_os_printf("Lowest Stack Pointer %p\n",
  442. acpi_gbl_lowest_stack_pointer);
  443. acpi_os_printf("Stack Use %X (%u)\n", temp,
  444. temp);
  445. acpi_os_printf("Deepest Procedure Nesting %u\n",
  446. acpi_gbl_deepest_nesting);
  447. #endif
  448. break;
  449. default:
  450. break;
  451. }
  452. acpi_os_printf("\n");
  453. return (AE_OK);
  454. }