proc_meminfo.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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. if(do_ram) {
  144. {
  145. static RRDSET *st_system_ram = NULL;
  146. static RRDDIM *rd_free = NULL, *rd_used = NULL, *rd_cached = NULL, *rd_buffers = NULL;
  147. if(unlikely(!st_system_ram)) {
  148. st_system_ram = rrdset_create_localhost(
  149. "system"
  150. , "ram"
  151. , NULL
  152. , "ram"
  153. , NULL
  154. , "System RAM"
  155. , "MiB"
  156. , PLUGIN_PROC_NAME
  157. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  158. , NETDATA_CHART_PRIO_SYSTEM_RAM
  159. , update_every
  160. , RRDSET_TYPE_STACKED
  161. );
  162. rd_free = rrddim_add(st_system_ram, "free", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  163. rd_used = rrddim_add(st_system_ram, "used", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  164. rd_cached = rrddim_add(st_system_ram, "cached", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  165. rd_buffers = rrddim_add(st_system_ram, "buffers", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  166. }
  167. else rrdset_next(st_system_ram);
  168. rrddim_set_by_pointer(st_system_ram, rd_free, MemFree);
  169. rrddim_set_by_pointer(st_system_ram, rd_used, MemUsed);
  170. rrddim_set_by_pointer(st_system_ram, rd_cached, MemCached);
  171. rrddim_set_by_pointer(st_system_ram, rd_buffers, Buffers);
  172. rrdset_done(st_system_ram);
  173. }
  174. if(arl_memavailable->flags & ARL_ENTRY_FLAG_FOUND) {
  175. static RRDSET *st_mem_available = NULL;
  176. static RRDDIM *rd_avail = NULL;
  177. if(unlikely(!st_mem_available)) {
  178. st_mem_available = rrdset_create_localhost(
  179. "mem"
  180. , "available"
  181. , NULL
  182. , "system"
  183. , NULL
  184. , "Available RAM for applications"
  185. , "MiB"
  186. , PLUGIN_PROC_NAME
  187. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  188. , NETDATA_CHART_PRIO_MEM_SYSTEM_AVAILABLE
  189. , update_every
  190. , RRDSET_TYPE_AREA
  191. );
  192. rd_avail = rrddim_add(st_mem_available, "MemAvailable", "avail", 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  193. }
  194. else rrdset_next(st_mem_available);
  195. rrddim_set_by_pointer(st_mem_available, rd_avail, MemAvailable);
  196. rrdset_done(st_mem_available);
  197. }
  198. }
  199. // --------------------------------------------------------------------
  200. unsigned long long SwapUsed = SwapTotal - SwapFree;
  201. if(do_swap == CONFIG_BOOLEAN_YES || (do_swap == CONFIG_BOOLEAN_AUTO &&
  202. (SwapTotal || SwapUsed || SwapFree ||
  203. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  204. do_swap = CONFIG_BOOLEAN_YES;
  205. static RRDSET *st_system_swap = NULL;
  206. static RRDDIM *rd_free = NULL, *rd_used = NULL;
  207. if(unlikely(!st_system_swap)) {
  208. st_system_swap = rrdset_create_localhost(
  209. "system"
  210. , "swap"
  211. , NULL
  212. , "swap"
  213. , NULL
  214. , "System Swap"
  215. , "MiB"
  216. , PLUGIN_PROC_NAME
  217. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  218. , NETDATA_CHART_PRIO_SYSTEM_SWAP
  219. , update_every
  220. , RRDSET_TYPE_STACKED
  221. );
  222. rrdset_flag_set(st_system_swap, RRDSET_FLAG_DETAIL);
  223. rd_free = rrddim_add(st_system_swap, "free", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  224. rd_used = rrddim_add(st_system_swap, "used", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  225. }
  226. else rrdset_next(st_system_swap);
  227. rrddim_set_by_pointer(st_system_swap, rd_used, SwapUsed);
  228. rrddim_set_by_pointer(st_system_swap, rd_free, SwapFree);
  229. rrdset_done(st_system_swap);
  230. }
  231. // --------------------------------------------------------------------
  232. if(arl_hwcorrupted->flags & ARL_ENTRY_FLAG_FOUND &&
  233. (do_hwcorrupt == CONFIG_BOOLEAN_YES || (do_hwcorrupt == CONFIG_BOOLEAN_AUTO &&
  234. (HardwareCorrupted > 0 ||
  235. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES)))) {
  236. do_hwcorrupt = CONFIG_BOOLEAN_YES;
  237. static RRDSET *st_mem_hwcorrupt = NULL;
  238. static RRDDIM *rd_corrupted = NULL;
  239. if(unlikely(!st_mem_hwcorrupt)) {
  240. st_mem_hwcorrupt = rrdset_create_localhost(
  241. "mem"
  242. , "hwcorrupt"
  243. , NULL
  244. , "ecc"
  245. , NULL
  246. , "Corrupted Memory, detected by ECC"
  247. , "MiB"
  248. , PLUGIN_PROC_NAME
  249. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  250. , NETDATA_CHART_PRIO_MEM_HW
  251. , update_every
  252. , RRDSET_TYPE_LINE
  253. );
  254. rrdset_flag_set(st_mem_hwcorrupt, RRDSET_FLAG_DETAIL);
  255. rd_corrupted = rrddim_add(st_mem_hwcorrupt, "HardwareCorrupted", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  256. }
  257. else rrdset_next(st_mem_hwcorrupt);
  258. rrddim_set_by_pointer(st_mem_hwcorrupt, rd_corrupted, HardwareCorrupted);
  259. rrdset_done(st_mem_hwcorrupt);
  260. }
  261. // --------------------------------------------------------------------
  262. if(do_committed) {
  263. static RRDSET *st_mem_committed = NULL;
  264. static RRDDIM *rd_committed = NULL;
  265. if(unlikely(!st_mem_committed)) {
  266. st_mem_committed = rrdset_create_localhost(
  267. "mem"
  268. , "committed"
  269. , NULL
  270. , "system"
  271. , NULL
  272. , "Committed (Allocated) Memory"
  273. , "MiB"
  274. , PLUGIN_PROC_NAME
  275. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  276. , NETDATA_CHART_PRIO_MEM_SYSTEM_COMMITTED
  277. , update_every
  278. , RRDSET_TYPE_AREA
  279. );
  280. rrdset_flag_set(st_mem_committed, RRDSET_FLAG_DETAIL);
  281. rd_committed = rrddim_add(st_mem_committed, "Committed_AS", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  282. }
  283. else rrdset_next(st_mem_committed);
  284. rrddim_set_by_pointer(st_mem_committed, rd_committed, Committed_AS);
  285. rrdset_done(st_mem_committed);
  286. }
  287. // --------------------------------------------------------------------
  288. if(do_writeback) {
  289. static RRDSET *st_mem_writeback = NULL;
  290. static RRDDIM *rd_dirty = NULL, *rd_writeback = NULL, *rd_fusewriteback = NULL, *rd_nfs_writeback = NULL, *rd_bounce = NULL;
  291. if(unlikely(!st_mem_writeback)) {
  292. st_mem_writeback = rrdset_create_localhost(
  293. "mem"
  294. , "writeback"
  295. , NULL
  296. , "kernel"
  297. , NULL
  298. , "Writeback Memory"
  299. , "MiB"
  300. , PLUGIN_PROC_NAME
  301. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  302. , NETDATA_CHART_PRIO_MEM_KERNEL
  303. , update_every
  304. , RRDSET_TYPE_LINE
  305. );
  306. rrdset_flag_set(st_mem_writeback, RRDSET_FLAG_DETAIL);
  307. rd_dirty = rrddim_add(st_mem_writeback, "Dirty", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  308. rd_writeback = rrddim_add(st_mem_writeback, "Writeback", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  309. rd_fusewriteback = rrddim_add(st_mem_writeback, "FuseWriteback", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  310. rd_nfs_writeback = rrddim_add(st_mem_writeback, "NfsWriteback", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  311. rd_bounce = rrddim_add(st_mem_writeback, "Bounce", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  312. }
  313. else rrdset_next(st_mem_writeback);
  314. rrddim_set_by_pointer(st_mem_writeback, rd_dirty, Dirty);
  315. rrddim_set_by_pointer(st_mem_writeback, rd_writeback, Writeback);
  316. rrddim_set_by_pointer(st_mem_writeback, rd_fusewriteback, WritebackTmp);
  317. rrddim_set_by_pointer(st_mem_writeback, rd_nfs_writeback, NFS_Unstable);
  318. rrddim_set_by_pointer(st_mem_writeback, rd_bounce, Bounce);
  319. rrdset_done(st_mem_writeback);
  320. }
  321. // --------------------------------------------------------------------
  322. if(do_kernel) {
  323. static RRDSET *st_mem_kernel = NULL;
  324. static RRDDIM *rd_slab = NULL, *rd_kernelstack = NULL, *rd_pagetables = NULL, *rd_vmallocused = NULL,
  325. *rd_percpu = NULL;
  326. if(unlikely(!st_mem_kernel)) {
  327. st_mem_kernel = rrdset_create_localhost(
  328. "mem"
  329. , "kernel"
  330. , NULL
  331. , "kernel"
  332. , NULL
  333. , "Memory Used by Kernel"
  334. , "MiB"
  335. , PLUGIN_PROC_NAME
  336. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  337. , NETDATA_CHART_PRIO_MEM_KERNEL + 1
  338. , update_every
  339. , RRDSET_TYPE_STACKED
  340. );
  341. rrdset_flag_set(st_mem_kernel, RRDSET_FLAG_DETAIL);
  342. rd_slab = rrddim_add(st_mem_kernel, "Slab", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  343. rd_kernelstack = rrddim_add(st_mem_kernel, "KernelStack", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  344. rd_pagetables = rrddim_add(st_mem_kernel, "PageTables", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  345. rd_vmallocused = rrddim_add(st_mem_kernel, "VmallocUsed", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  346. if (do_percpu)
  347. rd_percpu = rrddim_add(st_mem_kernel, "Percpu", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  348. }
  349. else rrdset_next(st_mem_kernel);
  350. rrddim_set_by_pointer(st_mem_kernel, rd_slab, Slab);
  351. rrddim_set_by_pointer(st_mem_kernel, rd_kernelstack, KernelStack);
  352. rrddim_set_by_pointer(st_mem_kernel, rd_pagetables, PageTables);
  353. rrddim_set_by_pointer(st_mem_kernel, rd_vmallocused, VmallocUsed);
  354. if (do_percpu)
  355. rrddim_set_by_pointer(st_mem_kernel, rd_percpu, Percpu);
  356. rrdset_done(st_mem_kernel);
  357. }
  358. // --------------------------------------------------------------------
  359. if(do_slab) {
  360. static RRDSET *st_mem_slab = NULL;
  361. static RRDDIM *rd_reclaimable = NULL, *rd_unreclaimable = NULL;
  362. if(unlikely(!st_mem_slab)) {
  363. st_mem_slab = rrdset_create_localhost(
  364. "mem"
  365. , "slab"
  366. , NULL
  367. , "slab"
  368. , NULL
  369. , "Reclaimable Kernel Memory"
  370. , "MiB"
  371. , PLUGIN_PROC_NAME
  372. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  373. , NETDATA_CHART_PRIO_MEM_SLAB
  374. , update_every
  375. , RRDSET_TYPE_STACKED
  376. );
  377. rrdset_flag_set(st_mem_slab, RRDSET_FLAG_DETAIL);
  378. rd_reclaimable = rrddim_add(st_mem_slab, "reclaimable", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  379. rd_unreclaimable = rrddim_add(st_mem_slab, "unreclaimable", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  380. }
  381. else rrdset_next(st_mem_slab);
  382. rrddim_set_by_pointer(st_mem_slab, rd_reclaimable, SReclaimable);
  383. rrddim_set_by_pointer(st_mem_slab, rd_unreclaimable, SUnreclaim);
  384. rrdset_done(st_mem_slab);
  385. }
  386. // --------------------------------------------------------------------
  387. if(do_hugepages == CONFIG_BOOLEAN_YES || (do_hugepages == CONFIG_BOOLEAN_AUTO &&
  388. ((Hugepagesize && HugePages_Total) ||
  389. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  390. do_hugepages = CONFIG_BOOLEAN_YES;
  391. static RRDSET *st_mem_hugepages = NULL;
  392. static RRDDIM *rd_used = NULL, *rd_free = NULL, *rd_rsvd = NULL, *rd_surp = NULL;
  393. if(unlikely(!st_mem_hugepages)) {
  394. st_mem_hugepages = rrdset_create_localhost(
  395. "mem"
  396. , "hugepages"
  397. , NULL
  398. , "hugepages"
  399. , NULL
  400. , "Dedicated HugePages Memory"
  401. , "MiB"
  402. , PLUGIN_PROC_NAME
  403. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  404. , NETDATA_CHART_PRIO_MEM_HUGEPAGES + 1
  405. , update_every
  406. , RRDSET_TYPE_STACKED
  407. );
  408. rrdset_flag_set(st_mem_hugepages, RRDSET_FLAG_DETAIL);
  409. rd_free = rrddim_add(st_mem_hugepages, "free", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  410. rd_used = rrddim_add(st_mem_hugepages, "used", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  411. rd_surp = rrddim_add(st_mem_hugepages, "surplus", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  412. rd_rsvd = rrddim_add(st_mem_hugepages, "reserved", NULL, Hugepagesize, 1024, RRD_ALGORITHM_ABSOLUTE);
  413. }
  414. else rrdset_next(st_mem_hugepages);
  415. rrddim_set_by_pointer(st_mem_hugepages, rd_used, HugePages_Total - HugePages_Free - HugePages_Rsvd);
  416. rrddim_set_by_pointer(st_mem_hugepages, rd_free, HugePages_Free);
  417. rrddim_set_by_pointer(st_mem_hugepages, rd_rsvd, HugePages_Rsvd);
  418. rrddim_set_by_pointer(st_mem_hugepages, rd_surp, HugePages_Surp);
  419. rrdset_done(st_mem_hugepages);
  420. }
  421. // --------------------------------------------------------------------
  422. if(do_transparent_hugepages == CONFIG_BOOLEAN_YES || (do_transparent_hugepages == CONFIG_BOOLEAN_AUTO &&
  423. (AnonHugePages ||
  424. ShmemHugePages ||
  425. netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
  426. do_transparent_hugepages = CONFIG_BOOLEAN_YES;
  427. static RRDSET *st_mem_transparent_hugepages = NULL;
  428. static RRDDIM *rd_anonymous = NULL, *rd_shared = NULL;
  429. if(unlikely(!st_mem_transparent_hugepages)) {
  430. st_mem_transparent_hugepages = rrdset_create_localhost(
  431. "mem"
  432. , "transparent_hugepages"
  433. , NULL
  434. , "hugepages"
  435. , NULL
  436. , "Transparent HugePages Memory"
  437. , "MiB"
  438. , PLUGIN_PROC_NAME
  439. , PLUGIN_PROC_MODULE_MEMINFO_NAME
  440. , NETDATA_CHART_PRIO_MEM_HUGEPAGES
  441. , update_every
  442. , RRDSET_TYPE_STACKED
  443. );
  444. rrdset_flag_set(st_mem_transparent_hugepages, RRDSET_FLAG_DETAIL);
  445. rd_anonymous = rrddim_add(st_mem_transparent_hugepages, "anonymous", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  446. rd_shared = rrddim_add(st_mem_transparent_hugepages, "shmem", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  447. }
  448. else rrdset_next(st_mem_transparent_hugepages);
  449. rrddim_set_by_pointer(st_mem_transparent_hugepages, rd_anonymous, AnonHugePages);
  450. rrddim_set_by_pointer(st_mem_transparent_hugepages, rd_shared, ShmemHugePages);
  451. rrdset_done(st_mem_transparent_hugepages);
  452. }
  453. return 0;
  454. }