proc_meminfo.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "plugin_proc.h"
  3. #define PLUGIN_PROC_MODULE_MEMINFO_NAME "/proc/meminfo"
  4. #define CONFIG_SECTION_PLUGIN_PROC_MEMINFO "plugin:" PLUGIN_PROC_CONFIG_NAME ":" PLUGIN_PROC_MODULE_MEMINFO_NAME
  5. int do_proc_meminfo(int update_every, usec_t dt) {
  6. (void)dt;
  7. static procfile *ff = NULL;
  8. static int do_ram = -1, do_swap = -1, do_hwcorrupt = -1, do_committed = -1, do_writeback = -1, do_kernel = -1, do_slab = -1, do_hugepages = -1, do_transparent_hugepages = -1;
  9. static int do_percpu = 0;
  10. static ARL_BASE *arl_base = NULL;
  11. static ARL_ENTRY *arl_hwcorrupted = NULL, *arl_memavailable = NULL;
  12. static unsigned long long
  13. MemTotal = 0,
  14. MemFree = 0,
  15. MemAvailable = 0,
  16. Buffers = 0,
  17. Cached = 0,
  18. //SwapCached = 0,
  19. //Active = 0,
  20. //Inactive = 0,
  21. //ActiveAnon = 0,
  22. //InactiveAnon = 0,
  23. //ActiveFile = 0,
  24. //InactiveFile = 0,
  25. //Unevictable = 0,
  26. //Mlocked = 0,
  27. SwapTotal = 0,
  28. SwapFree = 0,
  29. Dirty = 0,
  30. Writeback = 0,
  31. //AnonPages = 0,
  32. //Mapped = 0,
  33. Shmem = 0,
  34. Slab = 0,
  35. SReclaimable = 0,
  36. SUnreclaim = 0,
  37. KernelStack = 0,
  38. PageTables = 0,
  39. NFS_Unstable = 0,
  40. Bounce = 0,
  41. WritebackTmp = 0,
  42. //CommitLimit = 0,
  43. Committed_AS = 0,
  44. //VmallocTotal = 0,
  45. VmallocUsed = 0,
  46. //VmallocChunk = 0,
  47. Percpu = 0,
  48. AnonHugePages = 0,
  49. ShmemHugePages = 0,
  50. HugePages_Total = 0,
  51. HugePages_Free = 0,
  52. HugePages_Rsvd = 0,
  53. HugePages_Surp = 0,
  54. Hugepagesize = 0,
  55. //DirectMap4k = 0,
  56. //DirectMap2M = 0,
  57. HardwareCorrupted = 0;
  58. if(unlikely(!arl_base)) {
  59. do_ram = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "system ram", 1);
  60. do_swap = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "system swap", CONFIG_BOOLEAN_AUTO);
  61. do_hwcorrupt = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "hardware corrupted ECC", CONFIG_BOOLEAN_AUTO);
  62. do_committed = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "committed memory", 1);
  63. do_writeback = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "writeback memory", 1);
  64. do_kernel = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "kernel memory", 1);
  65. do_slab = config_get_boolean(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "slab memory", 1);
  66. do_hugepages = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "hugepages", CONFIG_BOOLEAN_AUTO);
  67. do_transparent_hugepages = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "transparent hugepages", CONFIG_BOOLEAN_AUTO);
  68. arl_base = arl_create("meminfo", NULL, 60);
  69. arl_expect(arl_base, "MemTotal", &MemTotal);
  70. arl_expect(arl_base, "MemFree", &MemFree);
  71. arl_memavailable = arl_expect(arl_base, "MemAvailable", &MemAvailable);
  72. arl_expect(arl_base, "Buffers", &Buffers);
  73. arl_expect(arl_base, "Cached", &Cached);
  74. //arl_expect(arl_base, "SwapCached", &SwapCached);
  75. //arl_expect(arl_base, "Active", &Active);
  76. //arl_expect(arl_base, "Inactive", &Inactive);
  77. //arl_expect(arl_base, "ActiveAnon", &ActiveAnon);
  78. //arl_expect(arl_base, "InactiveAnon", &InactiveAnon);
  79. //arl_expect(arl_base, "ActiveFile", &ActiveFile);
  80. //arl_expect(arl_base, "InactiveFile", &InactiveFile);
  81. //arl_expect(arl_base, "Unevictable", &Unevictable);
  82. //arl_expect(arl_base, "Mlocked", &Mlocked);
  83. arl_expect(arl_base, "SwapTotal", &SwapTotal);
  84. arl_expect(arl_base, "SwapFree", &SwapFree);
  85. arl_expect(arl_base, "Dirty", &Dirty);
  86. arl_expect(arl_base, "Writeback", &Writeback);
  87. //arl_expect(arl_base, "AnonPages", &AnonPages);
  88. //arl_expect(arl_base, "Mapped", &Mapped);
  89. arl_expect(arl_base, "Shmem", &Shmem);
  90. arl_expect(arl_base, "Slab", &Slab);
  91. arl_expect(arl_base, "SReclaimable", &SReclaimable);
  92. arl_expect(arl_base, "SUnreclaim", &SUnreclaim);
  93. arl_expect(arl_base, "KernelStack", &KernelStack);
  94. arl_expect(arl_base, "PageTables", &PageTables);
  95. arl_expect(arl_base, "NFS_Unstable", &NFS_Unstable);
  96. arl_expect(arl_base, "Bounce", &Bounce);
  97. arl_expect(arl_base, "WritebackTmp", &WritebackTmp);
  98. //arl_expect(arl_base, "CommitLimit", &CommitLimit);
  99. arl_expect(arl_base, "Committed_AS", &Committed_AS);
  100. //arl_expect(arl_base, "VmallocTotal", &VmallocTotal);
  101. arl_expect(arl_base, "VmallocUsed", &VmallocUsed);
  102. //arl_expect(arl_base, "VmallocChunk", &VmallocChunk);
  103. arl_expect(arl_base, "Percpu", &Percpu);
  104. arl_hwcorrupted = arl_expect(arl_base, "HardwareCorrupted", &HardwareCorrupted);
  105. arl_expect(arl_base, "AnonHugePages", &AnonHugePages);
  106. arl_expect(arl_base, "ShmemHugePages", &ShmemHugePages);
  107. arl_expect(arl_base, "HugePages_Total", &HugePages_Total);
  108. arl_expect(arl_base, "HugePages_Free", &HugePages_Free);
  109. arl_expect(arl_base, "HugePages_Rsvd", &HugePages_Rsvd);
  110. arl_expect(arl_base, "HugePages_Surp", &HugePages_Surp);
  111. arl_expect(arl_base, "Hugepagesize", &Hugepagesize);
  112. //arl_expect(arl_base, "DirectMap4k", &DirectMap4k);
  113. //arl_expect(arl_base, "DirectMap2M", &DirectMap2M);
  114. }
  115. if(unlikely(!ff)) {
  116. char filename[FILENAME_MAX + 1];
  117. snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/proc/meminfo");
  118. ff = procfile_open(config_get(CONFIG_SECTION_PLUGIN_PROC_MEMINFO, "filename to monitor", filename), " \t:", PROCFILE_FLAG_DEFAULT);
  119. if(unlikely(!ff))
  120. return 1;
  121. }
  122. ff = procfile_readall(ff);
  123. if(unlikely(!ff))
  124. return 0; // we return 0, so that we will retry to open it next time
  125. size_t lines = procfile_lines(ff), l;
  126. arl_begin(arl_base);
  127. static int first_ff_read = 1;
  128. for(l = 0; l < lines ;l++) {
  129. size_t words = procfile_linewords(ff, l);
  130. if(unlikely(words < 2)) continue;
  131. if (first_ff_read && !strcmp(procfile_lineword(ff, l, 0), "Percpu"))
  132. do_percpu = 1;
  133. if(unlikely(arl_check(arl_base,
  134. procfile_lineword(ff, l, 0),
  135. procfile_lineword(ff, l, 1)))) break;
  136. }
  137. if (first_ff_read)
  138. first_ff_read = 0;
  139. // --------------------------------------------------------------------
  140. // http://calimeroteknik.free.fr/blag/?article20/really-used-memory-on-gnu-linux
  141. unsigned long long MemCached = Cached + SReclaimable - Shmem;
  142. unsigned long long MemUsed = MemTotal - MemFree - MemCached - Buffers;
  143. // The Linux kernel doesn't report ZFS ARC usage as cache memory (the ARC is included in the total used system memory)
  144. MemCached += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
  145. MemUsed -= (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
  146. MemAvailable += (zfs_arcstats_shrinkable_cache_size_bytes / 1024);
  147. if(do_ram) {
  148. {
  149. static RRDSET *st_system_ram = NULL;
  150. static RRDDIM *rd_free = NULL, *rd_used = NULL, *rd_cached = NULL, *rd_buffers = NULL;
  151. if(unlikely(!st_system_ram)) {
  152. st_system_ram = rrdset_create_localhost(
  153. "system"
  154. , "ram"
  155. , NULL
  156. , "ram"
  157. , NULL
  158. , "System RAM"
  159. , "MiB"
  160. , PLUGIN_PROC_NAME
  161. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  162. , NETDATA_CHART_PRIO_SYSTEM_RAM
  163. , update_every
  164. , RRDSET_TYPE_STACKED
  165. );
  166. rd_free = rrddim_add(st_system_ram, "free", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  167. rd_used = rrddim_add(st_system_ram, "used", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  168. rd_cached = rrddim_add(st_system_ram, "cached", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  169. rd_buffers = rrddim_add(st_system_ram, "buffers", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  170. }
  171. else rrdset_next(st_system_ram);
  172. rrddim_set_by_pointer(st_system_ram, rd_free, MemFree);
  173. rrddim_set_by_pointer(st_system_ram, rd_used, MemUsed);
  174. rrddim_set_by_pointer(st_system_ram, rd_cached, MemCached);
  175. rrddim_set_by_pointer(st_system_ram, rd_buffers, Buffers);
  176. rrdset_done(st_system_ram);
  177. }
  178. if(arl_memavailable->flags & ARL_ENTRY_FLAG_FOUND) {
  179. static RRDSET *st_mem_available = NULL;
  180. static RRDDIM *rd_avail = NULL;
  181. if(unlikely(!st_mem_available)) {
  182. st_mem_available = rrdset_create_localhost(
  183. "mem"
  184. , "available"
  185. , NULL
  186. , "system"
  187. , NULL
  188. , "Available RAM for applications"
  189. , "MiB"
  190. , PLUGIN_PROC_NAME
  191. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  192. , NETDATA_CHART_PRIO_MEM_SYSTEM_AVAILABLE
  193. , update_every
  194. , RRDSET_TYPE_AREA
  195. );
  196. rd_avail = rrddim_add(st_mem_available, "MemAvailable", "avail", 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  197. }
  198. else rrdset_next(st_mem_available);
  199. rrddim_set_by_pointer(st_mem_available, rd_avail, MemAvailable);
  200. rrdset_done(st_mem_available);
  201. }
  202. }
  203. // --------------------------------------------------------------------
  204. unsigned long long SwapUsed = SwapTotal - SwapFree;
  205. if(do_swap == CONFIG_BOOLEAN_YES || (do_swap == CONFIG_BOOLEAN_AUTO &&
  206. (SwapTotal || SwapUsed || SwapFree ||
  207. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  208. do_swap = CONFIG_BOOLEAN_YES;
  209. static RRDSET *st_system_swap = NULL;
  210. static RRDDIM *rd_free = NULL, *rd_used = NULL;
  211. if(unlikely(!st_system_swap)) {
  212. st_system_swap = rrdset_create_localhost(
  213. "system"
  214. , "swap"
  215. , NULL
  216. , "swap"
  217. , NULL
  218. , "System Swap"
  219. , "MiB"
  220. , PLUGIN_PROC_NAME
  221. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  222. , NETDATA_CHART_PRIO_SYSTEM_SWAP
  223. , update_every
  224. , RRDSET_TYPE_STACKED
  225. );
  226. rrdset_flag_set(st_system_swap, RRDSET_FLAG_DETAIL);
  227. rd_free = rrddim_add(st_system_swap, "free", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  228. rd_used = rrddim_add(st_system_swap, "used", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  229. }
  230. else rrdset_next(st_system_swap);
  231. rrddim_set_by_pointer(st_system_swap, rd_used, SwapUsed);
  232. rrddim_set_by_pointer(st_system_swap, rd_free, SwapFree);
  233. rrdset_done(st_system_swap);
  234. }
  235. // --------------------------------------------------------------------
  236. if(arl_hwcorrupted->flags & ARL_ENTRY_FLAG_FOUND &&
  237. (do_hwcorrupt == CONFIG_BOOLEAN_YES || (do_hwcorrupt == CONFIG_BOOLEAN_AUTO &&
  238. (HardwareCorrupted > 0 ||
  239. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES)))) {
  240. do_hwcorrupt = CONFIG_BOOLEAN_YES;
  241. static RRDSET *st_mem_hwcorrupt = NULL;
  242. static RRDDIM *rd_corrupted = NULL;
  243. if(unlikely(!st_mem_hwcorrupt)) {
  244. st_mem_hwcorrupt = rrdset_create_localhost(
  245. "mem"
  246. , "hwcorrupt"
  247. , NULL
  248. , "ecc"
  249. , NULL
  250. , "Corrupted Memory, detected by ECC"
  251. , "MiB"
  252. , PLUGIN_PROC_NAME
  253. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  254. , NETDATA_CHART_PRIO_MEM_HW
  255. , update_every
  256. , RRDSET_TYPE_LINE
  257. );
  258. rrdset_flag_set(st_mem_hwcorrupt, RRDSET_FLAG_DETAIL);
  259. rd_corrupted = rrddim_add(st_mem_hwcorrupt, "HardwareCorrupted", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  260. }
  261. else rrdset_next(st_mem_hwcorrupt);
  262. rrddim_set_by_pointer(st_mem_hwcorrupt, rd_corrupted, HardwareCorrupted);
  263. rrdset_done(st_mem_hwcorrupt);
  264. }
  265. // --------------------------------------------------------------------
  266. if(do_committed) {
  267. static RRDSET *st_mem_committed = NULL;
  268. static RRDDIM *rd_committed = NULL;
  269. if(unlikely(!st_mem_committed)) {
  270. st_mem_committed = rrdset_create_localhost(
  271. "mem"
  272. , "committed"
  273. , NULL
  274. , "system"
  275. , NULL
  276. , "Committed (Allocated) Memory"
  277. , "MiB"
  278. , PLUGIN_PROC_NAME
  279. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  280. , NETDATA_CHART_PRIO_MEM_SYSTEM_COMMITTED
  281. , update_every
  282. , RRDSET_TYPE_AREA
  283. );
  284. rrdset_flag_set(st_mem_committed, RRDSET_FLAG_DETAIL);
  285. rd_committed = rrddim_add(st_mem_committed, "Committed_AS", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  286. }
  287. else rrdset_next(st_mem_committed);
  288. rrddim_set_by_pointer(st_mem_committed, rd_committed, Committed_AS);
  289. rrdset_done(st_mem_committed);
  290. }
  291. // --------------------------------------------------------------------
  292. if(do_writeback) {
  293. static RRDSET *st_mem_writeback = NULL;
  294. static RRDDIM *rd_dirty = NULL, *rd_writeback = NULL, *rd_fusewriteback = NULL, *rd_nfs_writeback = NULL, *rd_bounce = NULL;
  295. if(unlikely(!st_mem_writeback)) {
  296. st_mem_writeback = rrdset_create_localhost(
  297. "mem"
  298. , "writeback"
  299. , NULL
  300. , "kernel"
  301. , NULL
  302. , "Writeback Memory"
  303. , "MiB"
  304. , PLUGIN_PROC_NAME
  305. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  306. , NETDATA_CHART_PRIO_MEM_KERNEL
  307. , update_every
  308. , RRDSET_TYPE_LINE
  309. );
  310. rrdset_flag_set(st_mem_writeback, RRDSET_FLAG_DETAIL);
  311. rd_dirty = rrddim_add(st_mem_writeback, "Dirty", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  312. rd_writeback = rrddim_add(st_mem_writeback, "Writeback", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  313. rd_fusewriteback = rrddim_add(st_mem_writeback, "FuseWriteback", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  314. rd_nfs_writeback = rrddim_add(st_mem_writeback, "NfsWriteback", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  315. rd_bounce = rrddim_add(st_mem_writeback, "Bounce", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  316. }
  317. else rrdset_next(st_mem_writeback);
  318. rrddim_set_by_pointer(st_mem_writeback, rd_dirty, Dirty);
  319. rrddim_set_by_pointer(st_mem_writeback, rd_writeback, Writeback);
  320. rrddim_set_by_pointer(st_mem_writeback, rd_fusewriteback, WritebackTmp);
  321. rrddim_set_by_pointer(st_mem_writeback, rd_nfs_writeback, NFS_Unstable);
  322. rrddim_set_by_pointer(st_mem_writeback, rd_bounce, Bounce);
  323. rrdset_done(st_mem_writeback);
  324. }
  325. // --------------------------------------------------------------------
  326. if(do_kernel) {
  327. static RRDSET *st_mem_kernel = NULL;
  328. static RRDDIM *rd_slab = NULL, *rd_kernelstack = NULL, *rd_pagetables = NULL, *rd_vmallocused = NULL,
  329. *rd_percpu = NULL;
  330. if(unlikely(!st_mem_kernel)) {
  331. st_mem_kernel = rrdset_create_localhost(
  332. "mem"
  333. , "kernel"
  334. , NULL
  335. , "kernel"
  336. , NULL
  337. , "Memory Used by Kernel"
  338. , "MiB"
  339. , PLUGIN_PROC_NAME
  340. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  341. , NETDATA_CHART_PRIO_MEM_KERNEL + 1
  342. , update_every
  343. , RRDSET_TYPE_STACKED
  344. );
  345. rrdset_flag_set(st_mem_kernel, RRDSET_FLAG_DETAIL);
  346. rd_slab = rrddim_add(st_mem_kernel, "Slab", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  347. rd_kernelstack = rrddim_add(st_mem_kernel, "KernelStack", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  348. rd_pagetables = rrddim_add(st_mem_kernel, "PageTables", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  349. rd_vmallocused = rrddim_add(st_mem_kernel, "VmallocUsed", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  350. if (do_percpu)
  351. rd_percpu = rrddim_add(st_mem_kernel, "Percpu", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  352. }
  353. else rrdset_next(st_mem_kernel);
  354. rrddim_set_by_pointer(st_mem_kernel, rd_slab, Slab);
  355. rrddim_set_by_pointer(st_mem_kernel, rd_kernelstack, KernelStack);
  356. rrddim_set_by_pointer(st_mem_kernel, rd_pagetables, PageTables);
  357. rrddim_set_by_pointer(st_mem_kernel, rd_vmallocused, VmallocUsed);
  358. if (do_percpu)
  359. rrddim_set_by_pointer(st_mem_kernel, rd_percpu, Percpu);
  360. rrdset_done(st_mem_kernel);
  361. }
  362. // --------------------------------------------------------------------
  363. if(do_slab) {
  364. static RRDSET *st_mem_slab = NULL;
  365. static RRDDIM *rd_reclaimable = NULL, *rd_unreclaimable = NULL;
  366. if(unlikely(!st_mem_slab)) {
  367. st_mem_slab = rrdset_create_localhost(
  368. "mem"
  369. , "slab"
  370. , NULL
  371. , "slab"
  372. , NULL
  373. , "Reclaimable Kernel Memory"
  374. , "MiB"
  375. , PLUGIN_PROC_NAME
  376. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  377. , NETDATA_CHART_PRIO_MEM_SLAB
  378. , update_every
  379. , RRDSET_TYPE_STACKED
  380. );
  381. rrdset_flag_set(st_mem_slab, RRDSET_FLAG_DETAIL);
  382. rd_reclaimable = rrddim_add(st_mem_slab, "reclaimable", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  383. rd_unreclaimable = rrddim_add(st_mem_slab, "unreclaimable", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  384. }
  385. else rrdset_next(st_mem_slab);
  386. rrddim_set_by_pointer(st_mem_slab, rd_reclaimable, SReclaimable);
  387. rrddim_set_by_pointer(st_mem_slab, rd_unreclaimable, SUnreclaim);
  388. rrdset_done(st_mem_slab);
  389. }
  390. // --------------------------------------------------------------------
  391. if(do_hugepages == CONFIG_BOOLEAN_YES || (do_hugepages == CONFIG_BOOLEAN_AUTO &&
  392. ((Hugepagesize && HugePages_Total) ||
  393. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  394. do_hugepages = CONFIG_BOOLEAN_YES;
  395. static RRDSET *st_mem_hugepages = NULL;
  396. static RRDDIM *rd_used = NULL, *rd_free = NULL, *rd_rsvd = NULL, *rd_surp = NULL;
  397. if(unlikely(!st_mem_hugepages)) {
  398. st_mem_hugepages = rrdset_create_localhost(
  399. "mem"
  400. , "hugepages"
  401. , NULL
  402. , "hugepages"
  403. , NULL
  404. , "Dedicated HugePages Memory"
  405. , "MiB"
  406. , PLUGIN_PROC_NAME
  407. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  408. , NETDATA_CHART_PRIO_MEM_HUGEPAGES + 1
  409. , update_every
  410. , RRDSET_TYPE_STACKED
  411. );
  412. rrdset_flag_set(st_mem_hugepages, RRDSET_FLAG_DETAIL);
  413. rd_free = rrddim_add(st_mem_hugepages, "free", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  414. rd_used = rrddim_add(st_mem_hugepages, "used", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  415. rd_surp = rrddim_add(st_mem_hugepages, "surplus", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  416. rd_rsvd = rrddim_add(st_mem_hugepages, "reserved", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  417. }
  418. else rrdset_next(st_mem_hugepages);
  419. rrddim_set_by_pointer(st_mem_hugepages, rd_used, HugePages_Total - HugePages_Free - HugePages_Rsvd);
  420. rrddim_set_by_pointer(st_mem_hugepages, rd_free, HugePages_Free);
  421. rrddim_set_by_pointer(st_mem_hugepages, rd_rsvd, HugePages_Rsvd);
  422. rrddim_set_by_pointer(st_mem_hugepages, rd_surp, HugePages_Surp);
  423. rrdset_done(st_mem_hugepages);
  424. }
  425. // --------------------------------------------------------------------
  426. if(do_transparent_hugepages == CONFIG_BOOLEAN_YES || (do_transparent_hugepages == CONFIG_BOOLEAN_AUTO &&
  427. (AnonHugePages ||
  428. ShmemHugePages ||
  429. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  430. do_transparent_hugepages = CONFIG_BOOLEAN_YES;
  431. static RRDSET *st_mem_transparent_hugepages = NULL;
  432. static RRDDIM *rd_anonymous = NULL, *rd_shared = NULL;
  433. if(unlikely(!st_mem_transparent_hugepages)) {
  434. st_mem_transparent_hugepages = rrdset_create_localhost(
  435. "mem"
  436. , "transparent_hugepages"
  437. , NULL
  438. , "hugepages"
  439. , NULL
  440. , "Transparent HugePages Memory"
  441. , "MiB"
  442. , PLUGIN_PROC_NAME
  443. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  444. , NETDATA_CHART_PRIO_MEM_HUGEPAGES
  445. , update_every
  446. , RRDSET_TYPE_STACKED
  447. );
  448. rrdset_flag_set(st_mem_transparent_hugepages, RRDSET_FLAG_DETAIL);
  449. rd_anonymous = rrddim_add(st_mem_transparent_hugepages, "anonymous", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  450. rd_shared = rrddim_add(st_mem_transparent_hugepages, "shmem", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  451. }
  452. else rrdset_next(st_mem_transparent_hugepages);
  453. rrddim_set_by_pointer(st_mem_transparent_hugepages, rd_anonymous, AnonHugePages);
  454. rrddim_set_by_pointer(st_mem_transparent_hugepages, rd_shared, ShmemHugePages);
  455. rrdset_done(st_mem_transparent_hugepages);
  456. }
  457. return 0;
  458. }