test_memcontrol.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #define _GNU_SOURCE
  3. #include <linux/limits.h>
  4. #include <linux/oom.h>
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/stat.h>
  10. #include <sys/types.h>
  11. #include <unistd.h>
  12. #include <sys/socket.h>
  13. #include <sys/wait.h>
  14. #include <arpa/inet.h>
  15. #include <netinet/in.h>
  16. #include <netdb.h>
  17. #include <errno.h>
  18. #include <sys/mman.h>
  19. #include "kselftest.h"
  20. #include "cgroup_util.h"
  21. #define MEMCG_SOCKSTAT_WAIT_RETRIES 30
  22. static bool has_localevents;
  23. static bool has_recursiveprot;
  24. int get_temp_fd(void)
  25. {
  26. return open(".", O_TMPFILE | O_RDWR | O_EXCL);
  27. }
  28. int alloc_pagecache(int fd, size_t size)
  29. {
  30. char buf[PAGE_SIZE];
  31. struct stat st;
  32. int i;
  33. if (fstat(fd, &st))
  34. goto cleanup;
  35. size += st.st_size;
  36. if (ftruncate(fd, size))
  37. goto cleanup;
  38. for (i = 0; i < size; i += sizeof(buf))
  39. read(fd, buf, sizeof(buf));
  40. return 0;
  41. cleanup:
  42. return -1;
  43. }
  44. int alloc_anon(const char *cgroup, void *arg)
  45. {
  46. size_t size = (unsigned long)arg;
  47. char *buf, *ptr;
  48. buf = malloc(size);
  49. for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
  50. *ptr = 0;
  51. free(buf);
  52. return 0;
  53. }
  54. int is_swap_enabled(void)
  55. {
  56. char buf[PAGE_SIZE];
  57. const char delim[] = "\n";
  58. int cnt = 0;
  59. char *line;
  60. if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
  61. return -1;
  62. for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
  63. cnt++;
  64. return cnt > 1;
  65. }
  66. int set_oom_adj_score(int pid, int score)
  67. {
  68. char path[PATH_MAX];
  69. int fd, len;
  70. sprintf(path, "/proc/%d/oom_score_adj", pid);
  71. fd = open(path, O_WRONLY | O_APPEND);
  72. if (fd < 0)
  73. return fd;
  74. len = dprintf(fd, "%d", score);
  75. if (len < 0) {
  76. close(fd);
  77. return len;
  78. }
  79. close(fd);
  80. return 0;
  81. }
  82. /*
  83. * This test creates two nested cgroups with and without enabling
  84. * the memory controller.
  85. */
  86. static int test_memcg_subtree_control(const char *root)
  87. {
  88. char *parent, *child, *parent2 = NULL, *child2 = NULL;
  89. int ret = KSFT_FAIL;
  90. char buf[PAGE_SIZE];
  91. /* Create two nested cgroups with the memory controller enabled */
  92. parent = cg_name(root, "memcg_test_0");
  93. child = cg_name(root, "memcg_test_0/memcg_test_1");
  94. if (!parent || !child)
  95. goto cleanup_free;
  96. if (cg_create(parent))
  97. goto cleanup_free;
  98. if (cg_write(parent, "cgroup.subtree_control", "+memory"))
  99. goto cleanup_parent;
  100. if (cg_create(child))
  101. goto cleanup_parent;
  102. if (cg_read_strstr(child, "cgroup.controllers", "memory"))
  103. goto cleanup_child;
  104. /* Create two nested cgroups without enabling memory controller */
  105. parent2 = cg_name(root, "memcg_test_1");
  106. child2 = cg_name(root, "memcg_test_1/memcg_test_1");
  107. if (!parent2 || !child2)
  108. goto cleanup_free2;
  109. if (cg_create(parent2))
  110. goto cleanup_free2;
  111. if (cg_create(child2))
  112. goto cleanup_parent2;
  113. if (cg_read(child2, "cgroup.controllers", buf, sizeof(buf)))
  114. goto cleanup_all;
  115. if (!cg_read_strstr(child2, "cgroup.controllers", "memory"))
  116. goto cleanup_all;
  117. ret = KSFT_PASS;
  118. cleanup_all:
  119. cg_destroy(child2);
  120. cleanup_parent2:
  121. cg_destroy(parent2);
  122. cleanup_free2:
  123. free(parent2);
  124. free(child2);
  125. cleanup_child:
  126. cg_destroy(child);
  127. cleanup_parent:
  128. cg_destroy(parent);
  129. cleanup_free:
  130. free(parent);
  131. free(child);
  132. return ret;
  133. }
  134. static int alloc_anon_50M_check(const char *cgroup, void *arg)
  135. {
  136. size_t size = MB(50);
  137. char *buf, *ptr;
  138. long anon, current;
  139. int ret = -1;
  140. buf = malloc(size);
  141. if (buf == NULL) {
  142. fprintf(stderr, "malloc() failed\n");
  143. return -1;
  144. }
  145. for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
  146. *ptr = 0;
  147. current = cg_read_long(cgroup, "memory.current");
  148. if (current < size)
  149. goto cleanup;
  150. if (!values_close(size, current, 3))
  151. goto cleanup;
  152. anon = cg_read_key_long(cgroup, "memory.stat", "anon ");
  153. if (anon < 0)
  154. goto cleanup;
  155. if (!values_close(anon, current, 3))
  156. goto cleanup;
  157. ret = 0;
  158. cleanup:
  159. free(buf);
  160. return ret;
  161. }
  162. static int alloc_pagecache_50M_check(const char *cgroup, void *arg)
  163. {
  164. size_t size = MB(50);
  165. int ret = -1;
  166. long current, file;
  167. int fd;
  168. fd = get_temp_fd();
  169. if (fd < 0)
  170. return -1;
  171. if (alloc_pagecache(fd, size))
  172. goto cleanup;
  173. current = cg_read_long(cgroup, "memory.current");
  174. if (current < size)
  175. goto cleanup;
  176. file = cg_read_key_long(cgroup, "memory.stat", "file ");
  177. if (file < 0)
  178. goto cleanup;
  179. if (!values_close(file, current, 10))
  180. goto cleanup;
  181. ret = 0;
  182. cleanup:
  183. close(fd);
  184. return ret;
  185. }
  186. /*
  187. * This test create a memory cgroup, allocates
  188. * some anonymous memory and some pagecache
  189. * and checks memory.current, memory.peak, and some memory.stat values.
  190. */
  191. static int test_memcg_current_peak(const char *root)
  192. {
  193. int ret = KSFT_FAIL;
  194. long current, peak, peak_reset;
  195. char *memcg;
  196. bool fd2_closed = false, fd3_closed = false, fd4_closed = false;
  197. int peak_fd = -1, peak_fd2 = -1, peak_fd3 = -1, peak_fd4 = -1;
  198. struct stat ss;
  199. memcg = cg_name(root, "memcg_test");
  200. if (!memcg)
  201. goto cleanup;
  202. if (cg_create(memcg))
  203. goto cleanup;
  204. current = cg_read_long(memcg, "memory.current");
  205. if (current != 0)
  206. goto cleanup;
  207. peak = cg_read_long(memcg, "memory.peak");
  208. if (peak != 0)
  209. goto cleanup;
  210. if (cg_run(memcg, alloc_anon_50M_check, NULL))
  211. goto cleanup;
  212. peak = cg_read_long(memcg, "memory.peak");
  213. if (peak < MB(50))
  214. goto cleanup;
  215. /*
  216. * We'll open a few FDs for the same memory.peak file to exercise the free-path
  217. * We need at least three to be closed in a different order than writes occurred to test
  218. * the linked-list handling.
  219. */
  220. peak_fd = cg_open(memcg, "memory.peak", O_RDWR | O_APPEND | O_CLOEXEC);
  221. if (peak_fd == -1) {
  222. if (errno == ENOENT)
  223. ret = KSFT_SKIP;
  224. goto cleanup;
  225. }
  226. /*
  227. * Before we try to use memory.peak's fd, try to figure out whether
  228. * this kernel supports writing to that file in the first place. (by
  229. * checking the writable bit on the file's st_mode)
  230. */
  231. if (fstat(peak_fd, &ss))
  232. goto cleanup;
  233. if ((ss.st_mode & S_IWUSR) == 0) {
  234. ret = KSFT_SKIP;
  235. goto cleanup;
  236. }
  237. peak_fd2 = cg_open(memcg, "memory.peak", O_RDWR | O_APPEND | O_CLOEXEC);
  238. if (peak_fd2 == -1)
  239. goto cleanup;
  240. peak_fd3 = cg_open(memcg, "memory.peak", O_RDWR | O_APPEND | O_CLOEXEC);
  241. if (peak_fd3 == -1)
  242. goto cleanup;
  243. /* any non-empty string resets, but make it clear */
  244. static const char reset_string[] = "reset\n";
  245. peak_reset = write(peak_fd, reset_string, sizeof(reset_string));
  246. if (peak_reset != sizeof(reset_string))
  247. goto cleanup;
  248. peak_reset = write(peak_fd2, reset_string, sizeof(reset_string));
  249. if (peak_reset != sizeof(reset_string))
  250. goto cleanup;
  251. peak_reset = write(peak_fd3, reset_string, sizeof(reset_string));
  252. if (peak_reset != sizeof(reset_string))
  253. goto cleanup;
  254. /* Make sure a completely independent read isn't affected by our FD-local reset above*/
  255. peak = cg_read_long(memcg, "memory.peak");
  256. if (peak < MB(50))
  257. goto cleanup;
  258. fd2_closed = true;
  259. if (close(peak_fd2))
  260. goto cleanup;
  261. peak_fd4 = cg_open(memcg, "memory.peak", O_RDWR | O_APPEND | O_CLOEXEC);
  262. if (peak_fd4 == -1)
  263. goto cleanup;
  264. peak_reset = write(peak_fd4, reset_string, sizeof(reset_string));
  265. if (peak_reset != sizeof(reset_string))
  266. goto cleanup;
  267. peak = cg_read_long_fd(peak_fd);
  268. if (peak > MB(30) || peak < 0)
  269. goto cleanup;
  270. if (cg_run(memcg, alloc_pagecache_50M_check, NULL))
  271. goto cleanup;
  272. peak = cg_read_long(memcg, "memory.peak");
  273. if (peak < MB(50))
  274. goto cleanup;
  275. /* Make sure everything is back to normal */
  276. peak = cg_read_long_fd(peak_fd);
  277. if (peak < MB(50))
  278. goto cleanup;
  279. peak = cg_read_long_fd(peak_fd4);
  280. if (peak < MB(50))
  281. goto cleanup;
  282. fd3_closed = true;
  283. if (close(peak_fd3))
  284. goto cleanup;
  285. fd4_closed = true;
  286. if (close(peak_fd4))
  287. goto cleanup;
  288. ret = KSFT_PASS;
  289. cleanup:
  290. close(peak_fd);
  291. if (!fd2_closed)
  292. close(peak_fd2);
  293. if (!fd3_closed)
  294. close(peak_fd3);
  295. if (!fd4_closed)
  296. close(peak_fd4);
  297. cg_destroy(memcg);
  298. free(memcg);
  299. return ret;
  300. }
  301. static int alloc_pagecache_50M_noexit(const char *cgroup, void *arg)
  302. {
  303. int fd = (long)arg;
  304. int ppid = getppid();
  305. if (alloc_pagecache(fd, MB(50)))
  306. return -1;
  307. while (getppid() == ppid)
  308. sleep(1);
  309. return 0;
  310. }
  311. static int alloc_anon_noexit(const char *cgroup, void *arg)
  312. {
  313. int ppid = getppid();
  314. size_t size = (unsigned long)arg;
  315. char *buf, *ptr;
  316. buf = malloc(size);
  317. if (buf == NULL) {
  318. fprintf(stderr, "malloc() failed\n");
  319. return -1;
  320. }
  321. for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
  322. *ptr = 0;
  323. while (getppid() == ppid)
  324. sleep(1);
  325. free(buf);
  326. return 0;
  327. }
  328. /*
  329. * Wait until processes are killed asynchronously by the OOM killer
  330. * If we exceed a timeout, fail.
  331. */
  332. static int cg_test_proc_killed(const char *cgroup)
  333. {
  334. int limit;
  335. for (limit = 10; limit > 0; limit--) {
  336. if (cg_read_strcmp(cgroup, "cgroup.procs", "") == 0)
  337. return 0;
  338. usleep(100000);
  339. }
  340. return -1;
  341. }
  342. static bool reclaim_until(const char *memcg, long goal);
  343. /*
  344. * First, this test creates the following hierarchy:
  345. * A memory.min = 0, memory.max = 200M
  346. * A/B memory.min = 50M
  347. * A/B/C memory.min = 75M, memory.current = 50M
  348. * A/B/D memory.min = 25M, memory.current = 50M
  349. * A/B/E memory.min = 0, memory.current = 50M
  350. * A/B/F memory.min = 500M, memory.current = 0
  351. *
  352. * (or memory.low if we test soft protection)
  353. *
  354. * Usages are pagecache and the test keeps a running
  355. * process in every leaf cgroup.
  356. * Then it creates A/G and creates a significant
  357. * memory pressure in A.
  358. *
  359. * Then it checks actual memory usages and expects that:
  360. * A/B memory.current ~= 50M
  361. * A/B/C memory.current ~= 29M [memory.events:low > 0]
  362. * A/B/D memory.current ~= 21M [memory.events:low > 0]
  363. * A/B/E memory.current ~= 0 [memory.events:low == 0 if !memory_recursiveprot,
  364. * undefined otherwise]
  365. * A/B/F memory.current = 0 [memory.events:low == 0]
  366. * (for origin of the numbers, see model in memcg_protection.m.)
  367. *
  368. * After that it tries to allocate more than there is
  369. * unprotected memory in A available, and checks that:
  370. * a) memory.min protects pagecache even in this case,
  371. * b) memory.low allows reclaiming page cache with low events.
  372. *
  373. * Then we try to reclaim from A/B/C using memory.reclaim until its
  374. * usage reaches 10M.
  375. * This makes sure that:
  376. * (a) We ignore the protection of the reclaim target memcg.
  377. * (b) The previously calculated emin value (~29M) should be dismissed.
  378. */
  379. static int test_memcg_protection(const char *root, bool min)
  380. {
  381. int ret = KSFT_FAIL, rc;
  382. char *parent[3] = {NULL};
  383. char *children[4] = {NULL};
  384. const char *attribute = min ? "memory.min" : "memory.low";
  385. long c[4];
  386. long current;
  387. int i, attempts;
  388. int fd;
  389. fd = get_temp_fd();
  390. if (fd < 0)
  391. goto cleanup;
  392. parent[0] = cg_name(root, "memcg_test_0");
  393. if (!parent[0])
  394. goto cleanup;
  395. parent[1] = cg_name(parent[0], "memcg_test_1");
  396. if (!parent[1])
  397. goto cleanup;
  398. parent[2] = cg_name(parent[0], "memcg_test_2");
  399. if (!parent[2])
  400. goto cleanup;
  401. if (cg_create(parent[0]))
  402. goto cleanup;
  403. if (cg_read_long(parent[0], attribute)) {
  404. /* No memory.min on older kernels is fine */
  405. if (min)
  406. ret = KSFT_SKIP;
  407. goto cleanup;
  408. }
  409. if (cg_write(parent[0], "cgroup.subtree_control", "+memory"))
  410. goto cleanup;
  411. if (cg_write(parent[0], "memory.max", "200M"))
  412. goto cleanup;
  413. if (cg_write(parent[0], "memory.swap.max", "0"))
  414. goto cleanup;
  415. if (cg_create(parent[1]))
  416. goto cleanup;
  417. if (cg_write(parent[1], "cgroup.subtree_control", "+memory"))
  418. goto cleanup;
  419. if (cg_create(parent[2]))
  420. goto cleanup;
  421. for (i = 0; i < ARRAY_SIZE(children); i++) {
  422. children[i] = cg_name_indexed(parent[1], "child_memcg", i);
  423. if (!children[i])
  424. goto cleanup;
  425. if (cg_create(children[i]))
  426. goto cleanup;
  427. if (i > 2)
  428. continue;
  429. cg_run_nowait(children[i], alloc_pagecache_50M_noexit,
  430. (void *)(long)fd);
  431. }
  432. if (cg_write(parent[1], attribute, "50M"))
  433. goto cleanup;
  434. if (cg_write(children[0], attribute, "75M"))
  435. goto cleanup;
  436. if (cg_write(children[1], attribute, "25M"))
  437. goto cleanup;
  438. if (cg_write(children[2], attribute, "0"))
  439. goto cleanup;
  440. if (cg_write(children[3], attribute, "500M"))
  441. goto cleanup;
  442. attempts = 0;
  443. while (!values_close(cg_read_long(parent[1], "memory.current"),
  444. MB(150), 3)) {
  445. if (attempts++ > 5)
  446. break;
  447. sleep(1);
  448. }
  449. if (cg_run(parent[2], alloc_anon, (void *)MB(148)))
  450. goto cleanup;
  451. if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
  452. goto cleanup;
  453. for (i = 0; i < ARRAY_SIZE(children); i++)
  454. c[i] = cg_read_long(children[i], "memory.current");
  455. if (!values_close(c[0], MB(29), 15))
  456. goto cleanup;
  457. if (!values_close(c[1], MB(21), 20))
  458. goto cleanup;
  459. if (c[3] != 0)
  460. goto cleanup;
  461. rc = cg_run(parent[2], alloc_anon, (void *)MB(170));
  462. if (min && !rc)
  463. goto cleanup;
  464. else if (!min && rc) {
  465. fprintf(stderr,
  466. "memory.low prevents from allocating anon memory\n");
  467. goto cleanup;
  468. }
  469. current = min ? MB(50) : MB(30);
  470. if (!values_close(cg_read_long(parent[1], "memory.current"), current, 3))
  471. goto cleanup;
  472. if (!reclaim_until(children[0], MB(10)))
  473. goto cleanup;
  474. if (min) {
  475. ret = KSFT_PASS;
  476. goto cleanup;
  477. }
  478. /*
  479. * Child 2 has memory.low=0, but some low protection may still be
  480. * distributed down from its parent with memory.low=50M if cgroup2
  481. * memory_recursiveprot mount option is enabled. Ignore the low
  482. * event count in this case.
  483. */
  484. for (i = 0; i < ARRAY_SIZE(children); i++) {
  485. int ignore_low_events_index = has_recursiveprot ? 2 : -1;
  486. int no_low_events_index = 1;
  487. long low, oom;
  488. oom = cg_read_key_long(children[i], "memory.events", "oom ");
  489. low = cg_read_key_long(children[i], "memory.events", "low ");
  490. if (oom)
  491. goto cleanup;
  492. if (i == ignore_low_events_index)
  493. continue;
  494. if (i <= no_low_events_index && low <= 0)
  495. goto cleanup;
  496. if (i > no_low_events_index && low)
  497. goto cleanup;
  498. }
  499. ret = KSFT_PASS;
  500. cleanup:
  501. for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) {
  502. if (!children[i])
  503. continue;
  504. cg_destroy(children[i]);
  505. free(children[i]);
  506. }
  507. for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) {
  508. if (!parent[i])
  509. continue;
  510. cg_destroy(parent[i]);
  511. free(parent[i]);
  512. }
  513. close(fd);
  514. return ret;
  515. }
  516. static int test_memcg_min(const char *root)
  517. {
  518. return test_memcg_protection(root, true);
  519. }
  520. static int test_memcg_low(const char *root)
  521. {
  522. return test_memcg_protection(root, false);
  523. }
  524. static int alloc_pagecache_max_30M(const char *cgroup, void *arg)
  525. {
  526. size_t size = MB(50);
  527. int ret = -1;
  528. long current, high, max;
  529. int fd;
  530. high = cg_read_long(cgroup, "memory.high");
  531. max = cg_read_long(cgroup, "memory.max");
  532. if (high != MB(30) && max != MB(30))
  533. return -1;
  534. fd = get_temp_fd();
  535. if (fd < 0)
  536. return -1;
  537. if (alloc_pagecache(fd, size))
  538. goto cleanup;
  539. current = cg_read_long(cgroup, "memory.current");
  540. if (!values_close(current, MB(30), 5))
  541. goto cleanup;
  542. ret = 0;
  543. cleanup:
  544. close(fd);
  545. return ret;
  546. }
  547. /*
  548. * This test checks that memory.high limits the amount of
  549. * memory which can be consumed by either anonymous memory
  550. * or pagecache.
  551. */
  552. static int test_memcg_high(const char *root)
  553. {
  554. int ret = KSFT_FAIL;
  555. char *memcg;
  556. long high;
  557. memcg = cg_name(root, "memcg_test");
  558. if (!memcg)
  559. goto cleanup;
  560. if (cg_create(memcg))
  561. goto cleanup;
  562. if (cg_read_strcmp(memcg, "memory.high", "max\n"))
  563. goto cleanup;
  564. if (cg_write(memcg, "memory.swap.max", "0"))
  565. goto cleanup;
  566. if (cg_write(memcg, "memory.high", "30M"))
  567. goto cleanup;
  568. if (cg_run(memcg, alloc_anon, (void *)MB(31)))
  569. goto cleanup;
  570. if (!cg_run(memcg, alloc_pagecache_50M_check, NULL))
  571. goto cleanup;
  572. if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
  573. goto cleanup;
  574. high = cg_read_key_long(memcg, "memory.events", "high ");
  575. if (high <= 0)
  576. goto cleanup;
  577. ret = KSFT_PASS;
  578. cleanup:
  579. cg_destroy(memcg);
  580. free(memcg);
  581. return ret;
  582. }
  583. static int alloc_anon_mlock(const char *cgroup, void *arg)
  584. {
  585. size_t size = (size_t)arg;
  586. void *buf;
  587. buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
  588. 0, 0);
  589. if (buf == MAP_FAILED)
  590. return -1;
  591. mlock(buf, size);
  592. munmap(buf, size);
  593. return 0;
  594. }
  595. /*
  596. * This test checks that memory.high is able to throttle big single shot
  597. * allocation i.e. large allocation within one kernel entry.
  598. */
  599. static int test_memcg_high_sync(const char *root)
  600. {
  601. int ret = KSFT_FAIL, pid, fd = -1;
  602. char *memcg;
  603. long pre_high, pre_max;
  604. long post_high, post_max;
  605. memcg = cg_name(root, "memcg_test");
  606. if (!memcg)
  607. goto cleanup;
  608. if (cg_create(memcg))
  609. goto cleanup;
  610. pre_high = cg_read_key_long(memcg, "memory.events", "high ");
  611. pre_max = cg_read_key_long(memcg, "memory.events", "max ");
  612. if (pre_high < 0 || pre_max < 0)
  613. goto cleanup;
  614. if (cg_write(memcg, "memory.swap.max", "0"))
  615. goto cleanup;
  616. if (cg_write(memcg, "memory.high", "30M"))
  617. goto cleanup;
  618. if (cg_write(memcg, "memory.max", "140M"))
  619. goto cleanup;
  620. fd = memcg_prepare_for_wait(memcg);
  621. if (fd < 0)
  622. goto cleanup;
  623. pid = cg_run_nowait(memcg, alloc_anon_mlock, (void *)MB(200));
  624. if (pid < 0)
  625. goto cleanup;
  626. cg_wait_for(fd);
  627. post_high = cg_read_key_long(memcg, "memory.events", "high ");
  628. post_max = cg_read_key_long(memcg, "memory.events", "max ");
  629. if (post_high < 0 || post_max < 0)
  630. goto cleanup;
  631. if (pre_high == post_high || pre_max != post_max)
  632. goto cleanup;
  633. ret = KSFT_PASS;
  634. cleanup:
  635. if (fd >= 0)
  636. close(fd);
  637. cg_destroy(memcg);
  638. free(memcg);
  639. return ret;
  640. }
  641. /*
  642. * This test checks that memory.max limits the amount of
  643. * memory which can be consumed by either anonymous memory
  644. * or pagecache.
  645. */
  646. static int test_memcg_max(const char *root)
  647. {
  648. int ret = KSFT_FAIL;
  649. char *memcg;
  650. long current, max;
  651. memcg = cg_name(root, "memcg_test");
  652. if (!memcg)
  653. goto cleanup;
  654. if (cg_create(memcg))
  655. goto cleanup;
  656. if (cg_read_strcmp(memcg, "memory.max", "max\n"))
  657. goto cleanup;
  658. if (cg_write(memcg, "memory.swap.max", "0"))
  659. goto cleanup;
  660. if (cg_write(memcg, "memory.max", "30M"))
  661. goto cleanup;
  662. /* Should be killed by OOM killer */
  663. if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
  664. goto cleanup;
  665. if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
  666. goto cleanup;
  667. current = cg_read_long(memcg, "memory.current");
  668. if (current > MB(30) || !current)
  669. goto cleanup;
  670. max = cg_read_key_long(memcg, "memory.events", "max ");
  671. if (max <= 0)
  672. goto cleanup;
  673. ret = KSFT_PASS;
  674. cleanup:
  675. cg_destroy(memcg);
  676. free(memcg);
  677. return ret;
  678. }
  679. /*
  680. * Reclaim from @memcg until usage reaches @goal by writing to
  681. * memory.reclaim.
  682. *
  683. * This function will return false if the usage is already below the
  684. * goal.
  685. *
  686. * This function assumes that writing to memory.reclaim is the only
  687. * source of change in memory.current (no concurrent allocations or
  688. * reclaim).
  689. *
  690. * This function makes sure memory.reclaim is sane. It will return
  691. * false if memory.reclaim's error codes do not make sense, even if
  692. * the usage goal was satisfied.
  693. */
  694. static bool reclaim_until(const char *memcg, long goal)
  695. {
  696. char buf[64];
  697. int retries, err;
  698. long current, to_reclaim;
  699. bool reclaimed = false;
  700. for (retries = 5; retries > 0; retries--) {
  701. current = cg_read_long(memcg, "memory.current");
  702. if (current < goal || values_close(current, goal, 3))
  703. break;
  704. /* Did memory.reclaim return 0 incorrectly? */
  705. else if (reclaimed)
  706. return false;
  707. to_reclaim = current - goal;
  708. snprintf(buf, sizeof(buf), "%ld", to_reclaim);
  709. err = cg_write(memcg, "memory.reclaim", buf);
  710. if (!err)
  711. reclaimed = true;
  712. else if (err != -EAGAIN)
  713. return false;
  714. }
  715. return reclaimed;
  716. }
  717. /*
  718. * This test checks that memory.reclaim reclaims the given
  719. * amount of memory (from both anon and file, if possible).
  720. */
  721. static int test_memcg_reclaim(const char *root)
  722. {
  723. int ret = KSFT_FAIL;
  724. int fd = -1;
  725. int retries;
  726. char *memcg;
  727. long current, expected_usage;
  728. memcg = cg_name(root, "memcg_test");
  729. if (!memcg)
  730. goto cleanup;
  731. if (cg_create(memcg))
  732. goto cleanup;
  733. current = cg_read_long(memcg, "memory.current");
  734. if (current != 0)
  735. goto cleanup;
  736. fd = get_temp_fd();
  737. if (fd < 0)
  738. goto cleanup;
  739. cg_run_nowait(memcg, alloc_pagecache_50M_noexit, (void *)(long)fd);
  740. /*
  741. * If swap is enabled, try to reclaim from both anon and file, else try
  742. * to reclaim from file only.
  743. */
  744. if (is_swap_enabled()) {
  745. cg_run_nowait(memcg, alloc_anon_noexit, (void *) MB(50));
  746. expected_usage = MB(100);
  747. } else
  748. expected_usage = MB(50);
  749. /*
  750. * Wait until current usage reaches the expected usage (or we run out of
  751. * retries).
  752. */
  753. retries = 5;
  754. while (!values_close(cg_read_long(memcg, "memory.current"),
  755. expected_usage, 10)) {
  756. if (retries--) {
  757. sleep(1);
  758. continue;
  759. } else {
  760. fprintf(stderr,
  761. "failed to allocate %ld for memcg reclaim test\n",
  762. expected_usage);
  763. goto cleanup;
  764. }
  765. }
  766. /*
  767. * Reclaim until current reaches 30M, this makes sure we hit both anon
  768. * and file if swap is enabled.
  769. */
  770. if (!reclaim_until(memcg, MB(30)))
  771. goto cleanup;
  772. ret = KSFT_PASS;
  773. cleanup:
  774. cg_destroy(memcg);
  775. free(memcg);
  776. close(fd);
  777. return ret;
  778. }
  779. static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
  780. {
  781. long mem_max = (long)arg;
  782. size_t size = MB(50);
  783. char *buf, *ptr;
  784. long mem_current, swap_current;
  785. int ret = -1;
  786. buf = malloc(size);
  787. if (buf == NULL) {
  788. fprintf(stderr, "malloc() failed\n");
  789. return -1;
  790. }
  791. for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
  792. *ptr = 0;
  793. mem_current = cg_read_long(cgroup, "memory.current");
  794. if (!mem_current || !values_close(mem_current, mem_max, 3))
  795. goto cleanup;
  796. swap_current = cg_read_long(cgroup, "memory.swap.current");
  797. if (!swap_current ||
  798. !values_close(mem_current + swap_current, size, 3))
  799. goto cleanup;
  800. ret = 0;
  801. cleanup:
  802. free(buf);
  803. return ret;
  804. }
  805. /*
  806. * This test checks that memory.swap.max limits the amount of
  807. * anonymous memory which can be swapped out. Additionally, it verifies that
  808. * memory.swap.peak reflects the high watermark and can be reset.
  809. */
  810. static int test_memcg_swap_max_peak(const char *root)
  811. {
  812. int ret = KSFT_FAIL;
  813. char *memcg;
  814. long max, peak;
  815. struct stat ss;
  816. int swap_peak_fd = -1, mem_peak_fd = -1;
  817. /* any non-empty string resets */
  818. static const char reset_string[] = "foobarbaz";
  819. if (!is_swap_enabled())
  820. return KSFT_SKIP;
  821. memcg = cg_name(root, "memcg_test");
  822. if (!memcg)
  823. goto cleanup;
  824. if (cg_create(memcg))
  825. goto cleanup;
  826. if (cg_read_long(memcg, "memory.swap.current")) {
  827. ret = KSFT_SKIP;
  828. goto cleanup;
  829. }
  830. swap_peak_fd = cg_open(memcg, "memory.swap.peak",
  831. O_RDWR | O_APPEND | O_CLOEXEC);
  832. if (swap_peak_fd == -1) {
  833. if (errno == ENOENT)
  834. ret = KSFT_SKIP;
  835. goto cleanup;
  836. }
  837. /*
  838. * Before we try to use memory.swap.peak's fd, try to figure out
  839. * whether this kernel supports writing to that file in the first
  840. * place. (by checking the writable bit on the file's st_mode)
  841. */
  842. if (fstat(swap_peak_fd, &ss))
  843. goto cleanup;
  844. if ((ss.st_mode & S_IWUSR) == 0) {
  845. ret = KSFT_SKIP;
  846. goto cleanup;
  847. }
  848. mem_peak_fd = cg_open(memcg, "memory.peak", O_RDWR | O_APPEND | O_CLOEXEC);
  849. if (mem_peak_fd == -1)
  850. goto cleanup;
  851. if (cg_read_long(memcg, "memory.swap.peak"))
  852. goto cleanup;
  853. if (cg_read_long_fd(swap_peak_fd))
  854. goto cleanup;
  855. /* switch the swap and mem fds into local-peak tracking mode*/
  856. int peak_reset = write(swap_peak_fd, reset_string, sizeof(reset_string));
  857. if (peak_reset != sizeof(reset_string))
  858. goto cleanup;
  859. if (cg_read_long_fd(swap_peak_fd))
  860. goto cleanup;
  861. if (cg_read_long(memcg, "memory.peak"))
  862. goto cleanup;
  863. if (cg_read_long_fd(mem_peak_fd))
  864. goto cleanup;
  865. peak_reset = write(mem_peak_fd, reset_string, sizeof(reset_string));
  866. if (peak_reset != sizeof(reset_string))
  867. goto cleanup;
  868. if (cg_read_long_fd(mem_peak_fd))
  869. goto cleanup;
  870. if (cg_read_strcmp(memcg, "memory.max", "max\n"))
  871. goto cleanup;
  872. if (cg_read_strcmp(memcg, "memory.swap.max", "max\n"))
  873. goto cleanup;
  874. if (cg_write(memcg, "memory.swap.max", "30M"))
  875. goto cleanup;
  876. if (cg_write(memcg, "memory.max", "30M"))
  877. goto cleanup;
  878. /* Should be killed by OOM killer */
  879. if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
  880. goto cleanup;
  881. if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
  882. goto cleanup;
  883. if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
  884. goto cleanup;
  885. peak = cg_read_long(memcg, "memory.peak");
  886. if (peak < MB(29))
  887. goto cleanup;
  888. peak = cg_read_long(memcg, "memory.swap.peak");
  889. if (peak < MB(29))
  890. goto cleanup;
  891. peak = cg_read_long_fd(mem_peak_fd);
  892. if (peak < MB(29))
  893. goto cleanup;
  894. peak = cg_read_long_fd(swap_peak_fd);
  895. if (peak < MB(29))
  896. goto cleanup;
  897. /*
  898. * open, reset and close the peak swap on another FD to make sure
  899. * multiple extant fds don't corrupt the linked-list
  900. */
  901. peak_reset = cg_write(memcg, "memory.swap.peak", (char *)reset_string);
  902. if (peak_reset)
  903. goto cleanup;
  904. peak_reset = cg_write(memcg, "memory.peak", (char *)reset_string);
  905. if (peak_reset)
  906. goto cleanup;
  907. /* actually reset on the fds */
  908. peak_reset = write(swap_peak_fd, reset_string, sizeof(reset_string));
  909. if (peak_reset != sizeof(reset_string))
  910. goto cleanup;
  911. peak_reset = write(mem_peak_fd, reset_string, sizeof(reset_string));
  912. if (peak_reset != sizeof(reset_string))
  913. goto cleanup;
  914. peak = cg_read_long_fd(swap_peak_fd);
  915. if (peak > MB(10))
  916. goto cleanup;
  917. /*
  918. * The cgroup is now empty, but there may be a page or two associated
  919. * with the open FD accounted to it.
  920. */
  921. peak = cg_read_long_fd(mem_peak_fd);
  922. if (peak > MB(1))
  923. goto cleanup;
  924. if (cg_read_long(memcg, "memory.peak") < MB(29))
  925. goto cleanup;
  926. if (cg_read_long(memcg, "memory.swap.peak") < MB(29))
  927. goto cleanup;
  928. if (cg_run(memcg, alloc_anon_50M_check_swap, (void *)MB(30)))
  929. goto cleanup;
  930. max = cg_read_key_long(memcg, "memory.events", "max ");
  931. if (max <= 0)
  932. goto cleanup;
  933. peak = cg_read_long(memcg, "memory.peak");
  934. if (peak < MB(29))
  935. goto cleanup;
  936. peak = cg_read_long(memcg, "memory.swap.peak");
  937. if (peak < MB(29))
  938. goto cleanup;
  939. peak = cg_read_long_fd(mem_peak_fd);
  940. if (peak < MB(29))
  941. goto cleanup;
  942. peak = cg_read_long_fd(swap_peak_fd);
  943. if (peak < MB(19))
  944. goto cleanup;
  945. ret = KSFT_PASS;
  946. cleanup:
  947. if (mem_peak_fd != -1 && close(mem_peak_fd))
  948. ret = KSFT_FAIL;
  949. if (swap_peak_fd != -1 && close(swap_peak_fd))
  950. ret = KSFT_FAIL;
  951. cg_destroy(memcg);
  952. free(memcg);
  953. return ret;
  954. }
  955. /*
  956. * This test disables swapping and tries to allocate anonymous memory
  957. * up to OOM. Then it checks for oom and oom_kill events in
  958. * memory.events.
  959. */
  960. static int test_memcg_oom_events(const char *root)
  961. {
  962. int ret = KSFT_FAIL;
  963. char *memcg;
  964. memcg = cg_name(root, "memcg_test");
  965. if (!memcg)
  966. goto cleanup;
  967. if (cg_create(memcg))
  968. goto cleanup;
  969. if (cg_write(memcg, "memory.max", "30M"))
  970. goto cleanup;
  971. if (cg_write(memcg, "memory.swap.max", "0"))
  972. goto cleanup;
  973. if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
  974. goto cleanup;
  975. if (cg_read_strcmp(memcg, "cgroup.procs", ""))
  976. goto cleanup;
  977. if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
  978. goto cleanup;
  979. if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
  980. goto cleanup;
  981. ret = KSFT_PASS;
  982. cleanup:
  983. cg_destroy(memcg);
  984. free(memcg);
  985. return ret;
  986. }
  987. struct tcp_server_args {
  988. unsigned short port;
  989. int ctl[2];
  990. };
  991. static int tcp_server(const char *cgroup, void *arg)
  992. {
  993. struct tcp_server_args *srv_args = arg;
  994. struct sockaddr_in6 saddr = { 0 };
  995. socklen_t slen = sizeof(saddr);
  996. int sk, client_sk, ctl_fd, yes = 1, ret = -1;
  997. close(srv_args->ctl[0]);
  998. ctl_fd = srv_args->ctl[1];
  999. saddr.sin6_family = AF_INET6;
  1000. saddr.sin6_addr = in6addr_any;
  1001. saddr.sin6_port = htons(srv_args->port);
  1002. sk = socket(AF_INET6, SOCK_STREAM, 0);
  1003. if (sk < 0)
  1004. return ret;
  1005. if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
  1006. goto cleanup;
  1007. if (bind(sk, (struct sockaddr *)&saddr, slen)) {
  1008. write(ctl_fd, &errno, sizeof(errno));
  1009. goto cleanup;
  1010. }
  1011. if (listen(sk, 1))
  1012. goto cleanup;
  1013. ret = 0;
  1014. if (write(ctl_fd, &ret, sizeof(ret)) != sizeof(ret)) {
  1015. ret = -1;
  1016. goto cleanup;
  1017. }
  1018. client_sk = accept(sk, NULL, NULL);
  1019. if (client_sk < 0)
  1020. goto cleanup;
  1021. ret = -1;
  1022. for (;;) {
  1023. uint8_t buf[0x100000];
  1024. if (write(client_sk, buf, sizeof(buf)) <= 0) {
  1025. if (errno == ECONNRESET)
  1026. ret = 0;
  1027. break;
  1028. }
  1029. }
  1030. close(client_sk);
  1031. cleanup:
  1032. close(sk);
  1033. return ret;
  1034. }
  1035. static int tcp_client(const char *cgroup, unsigned short port)
  1036. {
  1037. const char server[] = "localhost";
  1038. struct addrinfo *ai;
  1039. char servport[6];
  1040. int retries = 0x10; /* nice round number */
  1041. int sk, ret;
  1042. long allocated;
  1043. allocated = cg_read_long(cgroup, "memory.current");
  1044. snprintf(servport, sizeof(servport), "%hd", port);
  1045. ret = getaddrinfo(server, servport, NULL, &ai);
  1046. if (ret)
  1047. return ret;
  1048. sk = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
  1049. if (sk < 0)
  1050. goto free_ainfo;
  1051. ret = connect(sk, ai->ai_addr, ai->ai_addrlen);
  1052. if (ret < 0)
  1053. goto close_sk;
  1054. ret = KSFT_FAIL;
  1055. while (retries--) {
  1056. uint8_t buf[0x100000];
  1057. long current, sock;
  1058. if (read(sk, buf, sizeof(buf)) <= 0)
  1059. goto close_sk;
  1060. current = cg_read_long(cgroup, "memory.current");
  1061. sock = cg_read_key_long(cgroup, "memory.stat", "sock ");
  1062. if (current < 0 || sock < 0)
  1063. goto close_sk;
  1064. /* exclude the memory not related to socket connection */
  1065. if (values_close(current - allocated, sock, 10)) {
  1066. ret = KSFT_PASS;
  1067. break;
  1068. }
  1069. }
  1070. close_sk:
  1071. close(sk);
  1072. free_ainfo:
  1073. freeaddrinfo(ai);
  1074. return ret;
  1075. }
  1076. /*
  1077. * This test checks socket memory accounting.
  1078. * The test forks a TCP server listens on a random port between 1000
  1079. * and 61000. Once it gets a client connection, it starts writing to
  1080. * its socket.
  1081. * The TCP client interleaves reads from the socket with check whether
  1082. * memory.current and memory.stat.sock are similar.
  1083. */
  1084. static int test_memcg_sock(const char *root)
  1085. {
  1086. int bind_retries = 5, ret = KSFT_FAIL, pid, err;
  1087. unsigned short port;
  1088. char *memcg;
  1089. long sock_post = -1;
  1090. memcg = cg_name(root, "memcg_test");
  1091. if (!memcg)
  1092. goto cleanup;
  1093. if (cg_create(memcg))
  1094. goto cleanup;
  1095. while (bind_retries--) {
  1096. struct tcp_server_args args;
  1097. if (pipe(args.ctl))
  1098. goto cleanup;
  1099. port = args.port = 1000 + rand() % 60000;
  1100. pid = cg_run_nowait(memcg, tcp_server, &args);
  1101. if (pid < 0)
  1102. goto cleanup;
  1103. close(args.ctl[1]);
  1104. if (read(args.ctl[0], &err, sizeof(err)) != sizeof(err))
  1105. goto cleanup;
  1106. close(args.ctl[0]);
  1107. if (!err)
  1108. break;
  1109. if (err != EADDRINUSE)
  1110. goto cleanup;
  1111. waitpid(pid, NULL, 0);
  1112. }
  1113. if (err == EADDRINUSE) {
  1114. ret = KSFT_SKIP;
  1115. goto cleanup;
  1116. }
  1117. if (tcp_client(memcg, port) != KSFT_PASS)
  1118. goto cleanup;
  1119. waitpid(pid, &err, 0);
  1120. if (WEXITSTATUS(err))
  1121. goto cleanup;
  1122. if (cg_read_long(memcg, "memory.current") < 0)
  1123. goto cleanup;
  1124. /*
  1125. * memory.stat is updated asynchronously via the memcg rstat
  1126. * flushing worker, which runs periodically (every 2 seconds,
  1127. * see FLUSH_TIME). On a busy system, the "sock " counter may
  1128. * stay non-zero for a short period of time after the TCP
  1129. * connection is closed and all socket memory has been
  1130. * uncharged.
  1131. *
  1132. * Poll memory.stat for up to 3 seconds (~FLUSH_TIME plus some
  1133. * scheduling slack) and require that the "sock " counter
  1134. * eventually drops to zero.
  1135. */
  1136. sock_post = cg_read_key_long_poll(memcg, "memory.stat", "sock ", 0,
  1137. MEMCG_SOCKSTAT_WAIT_RETRIES,
  1138. DEFAULT_WAIT_INTERVAL_US);
  1139. if (sock_post)
  1140. goto cleanup;
  1141. ret = KSFT_PASS;
  1142. cleanup:
  1143. cg_destroy(memcg);
  1144. free(memcg);
  1145. return ret;
  1146. }
  1147. /*
  1148. * This test disables swapping and tries to allocate anonymous memory
  1149. * up to OOM with memory.group.oom set. Then it checks that all
  1150. * processes in the leaf were killed. It also checks that oom_events
  1151. * were propagated to the parent level.
  1152. */
  1153. static int test_memcg_oom_group_leaf_events(const char *root)
  1154. {
  1155. int ret = KSFT_FAIL;
  1156. char *parent, *child;
  1157. long parent_oom_events;
  1158. parent = cg_name(root, "memcg_test_0");
  1159. child = cg_name(root, "memcg_test_0/memcg_test_1");
  1160. if (!parent || !child)
  1161. goto cleanup;
  1162. if (cg_create(parent))
  1163. goto cleanup;
  1164. if (cg_create(child))
  1165. goto cleanup;
  1166. if (cg_write(parent, "cgroup.subtree_control", "+memory"))
  1167. goto cleanup;
  1168. if (cg_write(child, "memory.max", "50M"))
  1169. goto cleanup;
  1170. if (cg_write(child, "memory.swap.max", "0"))
  1171. goto cleanup;
  1172. if (cg_write(child, "memory.oom.group", "1"))
  1173. goto cleanup;
  1174. cg_run_nowait(parent, alloc_anon_noexit, (void *) MB(60));
  1175. cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
  1176. cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
  1177. if (!cg_run(child, alloc_anon, (void *)MB(100)))
  1178. goto cleanup;
  1179. if (cg_test_proc_killed(child))
  1180. goto cleanup;
  1181. if (cg_read_key_long(child, "memory.events", "oom_kill ") <= 0)
  1182. goto cleanup;
  1183. parent_oom_events = cg_read_key_long(
  1184. parent, "memory.events", "oom_kill ");
  1185. /*
  1186. * If memory_localevents is not enabled (the default), the parent should
  1187. * count OOM events in its children groups. Otherwise, it should not
  1188. * have observed any events.
  1189. */
  1190. if (has_localevents && parent_oom_events != 0)
  1191. goto cleanup;
  1192. else if (!has_localevents && parent_oom_events <= 0)
  1193. goto cleanup;
  1194. ret = KSFT_PASS;
  1195. cleanup:
  1196. if (child)
  1197. cg_destroy(child);
  1198. if (parent)
  1199. cg_destroy(parent);
  1200. free(child);
  1201. free(parent);
  1202. return ret;
  1203. }
  1204. /*
  1205. * This test disables swapping and tries to allocate anonymous memory
  1206. * up to OOM with memory.group.oom set. Then it checks that all
  1207. * processes in the parent and leaf were killed.
  1208. */
  1209. static int test_memcg_oom_group_parent_events(const char *root)
  1210. {
  1211. int ret = KSFT_FAIL;
  1212. char *parent, *child;
  1213. parent = cg_name(root, "memcg_test_0");
  1214. child = cg_name(root, "memcg_test_0/memcg_test_1");
  1215. if (!parent || !child)
  1216. goto cleanup;
  1217. if (cg_create(parent))
  1218. goto cleanup;
  1219. if (cg_create(child))
  1220. goto cleanup;
  1221. if (cg_write(parent, "memory.max", "80M"))
  1222. goto cleanup;
  1223. if (cg_write(parent, "memory.swap.max", "0"))
  1224. goto cleanup;
  1225. if (cg_write(parent, "memory.oom.group", "1"))
  1226. goto cleanup;
  1227. cg_run_nowait(parent, alloc_anon_noexit, (void *) MB(60));
  1228. cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
  1229. cg_run_nowait(child, alloc_anon_noexit, (void *) MB(1));
  1230. if (!cg_run(child, alloc_anon, (void *)MB(100)))
  1231. goto cleanup;
  1232. if (cg_test_proc_killed(child))
  1233. goto cleanup;
  1234. if (cg_test_proc_killed(parent))
  1235. goto cleanup;
  1236. ret = KSFT_PASS;
  1237. cleanup:
  1238. if (child)
  1239. cg_destroy(child);
  1240. if (parent)
  1241. cg_destroy(parent);
  1242. free(child);
  1243. free(parent);
  1244. return ret;
  1245. }
  1246. /*
  1247. * This test disables swapping and tries to allocate anonymous memory
  1248. * up to OOM with memory.group.oom set. Then it checks that all
  1249. * processes were killed except those set with OOM_SCORE_ADJ_MIN
  1250. */
  1251. static int test_memcg_oom_group_score_events(const char *root)
  1252. {
  1253. int ret = KSFT_FAIL;
  1254. char *memcg;
  1255. int safe_pid;
  1256. memcg = cg_name(root, "memcg_test_0");
  1257. if (!memcg)
  1258. goto cleanup;
  1259. if (cg_create(memcg))
  1260. goto cleanup;
  1261. if (cg_write(memcg, "memory.max", "50M"))
  1262. goto cleanup;
  1263. if (cg_write(memcg, "memory.swap.max", "0"))
  1264. goto cleanup;
  1265. if (cg_write(memcg, "memory.oom.group", "1"))
  1266. goto cleanup;
  1267. safe_pid = cg_run_nowait(memcg, alloc_anon_noexit, (void *) MB(1));
  1268. if (set_oom_adj_score(safe_pid, OOM_SCORE_ADJ_MIN))
  1269. goto cleanup;
  1270. cg_run_nowait(memcg, alloc_anon_noexit, (void *) MB(1));
  1271. if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
  1272. goto cleanup;
  1273. if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 3)
  1274. goto cleanup;
  1275. if (kill(safe_pid, SIGKILL))
  1276. goto cleanup;
  1277. ret = KSFT_PASS;
  1278. cleanup:
  1279. if (memcg)
  1280. cg_destroy(memcg);
  1281. free(memcg);
  1282. return ret;
  1283. }
  1284. #define T(x) { x, #x }
  1285. struct memcg_test {
  1286. int (*fn)(const char *root);
  1287. const char *name;
  1288. } tests[] = {
  1289. T(test_memcg_subtree_control),
  1290. T(test_memcg_current_peak),
  1291. T(test_memcg_min),
  1292. T(test_memcg_low),
  1293. T(test_memcg_high),
  1294. T(test_memcg_high_sync),
  1295. T(test_memcg_max),
  1296. T(test_memcg_reclaim),
  1297. T(test_memcg_oom_events),
  1298. T(test_memcg_swap_max_peak),
  1299. T(test_memcg_sock),
  1300. T(test_memcg_oom_group_leaf_events),
  1301. T(test_memcg_oom_group_parent_events),
  1302. T(test_memcg_oom_group_score_events),
  1303. };
  1304. #undef T
  1305. int main(int argc, char **argv)
  1306. {
  1307. char root[PATH_MAX];
  1308. int i, proc_status;
  1309. ksft_print_header();
  1310. ksft_set_plan(ARRAY_SIZE(tests));
  1311. if (cg_find_unified_root(root, sizeof(root), NULL))
  1312. ksft_exit_skip("cgroup v2 isn't mounted\n");
  1313. /*
  1314. * Check that memory controller is available:
  1315. * memory is listed in cgroup.controllers
  1316. */
  1317. if (cg_read_strstr(root, "cgroup.controllers", "memory"))
  1318. ksft_exit_skip("memory controller isn't available\n");
  1319. if (cg_read_strstr(root, "cgroup.subtree_control", "memory"))
  1320. if (cg_write(root, "cgroup.subtree_control", "+memory"))
  1321. ksft_exit_skip("Failed to set memory controller\n");
  1322. proc_status = proc_mount_contains("memory_recursiveprot");
  1323. if (proc_status < 0)
  1324. ksft_exit_skip("Failed to query cgroup mount option\n");
  1325. has_recursiveprot = proc_status;
  1326. proc_status = proc_mount_contains("memory_localevents");
  1327. if (proc_status < 0)
  1328. ksft_exit_skip("Failed to query cgroup mount option\n");
  1329. has_localevents = proc_status;
  1330. for (i = 0; i < ARRAY_SIZE(tests); i++) {
  1331. switch (tests[i].fn(root)) {
  1332. case KSFT_PASS:
  1333. ksft_test_result_pass("%s\n", tests[i].name);
  1334. break;
  1335. case KSFT_SKIP:
  1336. ksft_test_result_skip("%s\n", tests[i].name);
  1337. break;
  1338. default:
  1339. ksft_test_result_fail("%s\n", tests[i].name);
  1340. break;
  1341. }
  1342. }
  1343. ksft_finished();
  1344. }