selftests: cgroup/memcontrol: add basic test for socket accounting
[linux-2.6-microblaze.git] / tools / testing / selftests / cgroup / test_memcontrol.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #define _GNU_SOURCE
3
4 #include <linux/limits.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
19 #include "../kselftest.h"
20 #include "cgroup_util.h"
21
22 /*
23  * This test creates two nested cgroups with and without enabling
24  * the memory controller.
25  */
26 static int test_memcg_subtree_control(const char *root)
27 {
28         char *parent, *child, *parent2, *child2;
29         int ret = KSFT_FAIL;
30         char buf[PAGE_SIZE];
31
32         /* Create two nested cgroups with the memory controller enabled */
33         parent = cg_name(root, "memcg_test_0");
34         child = cg_name(root, "memcg_test_0/memcg_test_1");
35         if (!parent || !child)
36                 goto cleanup;
37
38         if (cg_create(parent))
39                 goto cleanup;
40
41         if (cg_write(parent, "cgroup.subtree_control", "+memory"))
42                 goto cleanup;
43
44         if (cg_create(child))
45                 goto cleanup;
46
47         if (cg_read_strstr(child, "cgroup.controllers", "memory"))
48                 goto cleanup;
49
50         /* Create two nested cgroups without enabling memory controller */
51         parent2 = cg_name(root, "memcg_test_1");
52         child2 = cg_name(root, "memcg_test_1/memcg_test_1");
53         if (!parent2 || !child2)
54                 goto cleanup;
55
56         if (cg_create(parent2))
57                 goto cleanup;
58
59         if (cg_create(child2))
60                 goto cleanup;
61
62         if (cg_read(child2, "cgroup.controllers", buf, sizeof(buf)))
63                 goto cleanup;
64
65         if (!cg_read_strstr(child2, "cgroup.controllers", "memory"))
66                 goto cleanup;
67
68         ret = KSFT_PASS;
69
70 cleanup:
71         cg_destroy(child);
72         cg_destroy(parent);
73         free(parent);
74         free(child);
75
76         cg_destroy(child2);
77         cg_destroy(parent2);
78         free(parent2);
79         free(child2);
80
81         return ret;
82 }
83
84 static int alloc_anon_50M_check(const char *cgroup, void *arg)
85 {
86         size_t size = MB(50);
87         char *buf, *ptr;
88         long anon, current;
89         int ret = -1;
90
91         buf = malloc(size);
92         for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
93                 *ptr = 0;
94
95         current = cg_read_long(cgroup, "memory.current");
96         if (current < size)
97                 goto cleanup;
98
99         if (!values_close(size, current, 3))
100                 goto cleanup;
101
102         anon = cg_read_key_long(cgroup, "memory.stat", "anon ");
103         if (anon < 0)
104                 goto cleanup;
105
106         if (!values_close(anon, current, 3))
107                 goto cleanup;
108
109         ret = 0;
110 cleanup:
111         free(buf);
112         return ret;
113 }
114
115 static int alloc_pagecache_50M_check(const char *cgroup, void *arg)
116 {
117         size_t size = MB(50);
118         int ret = -1;
119         long current, file;
120         int fd;
121
122         fd = get_temp_fd();
123         if (fd < 0)
124                 return -1;
125
126         if (alloc_pagecache(fd, size))
127                 goto cleanup;
128
129         current = cg_read_long(cgroup, "memory.current");
130         if (current < size)
131                 goto cleanup;
132
133         file = cg_read_key_long(cgroup, "memory.stat", "file ");
134         if (file < 0)
135                 goto cleanup;
136
137         if (!values_close(file, current, 10))
138                 goto cleanup;
139
140         ret = 0;
141
142 cleanup:
143         close(fd);
144         return ret;
145 }
146
147 /*
148  * This test create a memory cgroup, allocates
149  * some anonymous memory and some pagecache
150  * and check memory.current and some memory.stat values.
151  */
152 static int test_memcg_current(const char *root)
153 {
154         int ret = KSFT_FAIL;
155         long current;
156         char *memcg;
157
158         memcg = cg_name(root, "memcg_test");
159         if (!memcg)
160                 goto cleanup;
161
162         if (cg_create(memcg))
163                 goto cleanup;
164
165         current = cg_read_long(memcg, "memory.current");
166         if (current != 0)
167                 goto cleanup;
168
169         if (cg_run(memcg, alloc_anon_50M_check, NULL))
170                 goto cleanup;
171
172         if (cg_run(memcg, alloc_pagecache_50M_check, NULL))
173                 goto cleanup;
174
175         ret = KSFT_PASS;
176
177 cleanup:
178         cg_destroy(memcg);
179         free(memcg);
180
181         return ret;
182 }
183
184 static int alloc_pagecache_50M(const char *cgroup, void *arg)
185 {
186         int fd = (long)arg;
187
188         return alloc_pagecache(fd, MB(50));
189 }
190
191 static int alloc_pagecache_50M_noexit(const char *cgroup, void *arg)
192 {
193         int fd = (long)arg;
194         int ppid = getppid();
195
196         if (alloc_pagecache(fd, MB(50)))
197                 return -1;
198
199         while (getppid() == ppid)
200                 sleep(1);
201
202         return 0;
203 }
204
205 /*
206  * First, this test creates the following hierarchy:
207  * A       memory.min = 50M,  memory.max = 200M
208  * A/B     memory.min = 50M,  memory.current = 50M
209  * A/B/C   memory.min = 75M,  memory.current = 50M
210  * A/B/D   memory.min = 25M,  memory.current = 50M
211  * A/B/E   memory.min = 500M, memory.current = 0
212  * A/B/F   memory.min = 0,    memory.current = 50M
213  *
214  * Usages are pagecache, but the test keeps a running
215  * process in every leaf cgroup.
216  * Then it creates A/G and creates a significant
217  * memory pressure in it.
218  *
219  * A/B    memory.current ~= 50M
220  * A/B/C  memory.current ~= 33M
221  * A/B/D  memory.current ~= 17M
222  * A/B/E  memory.current ~= 0
223  *
224  * After that it tries to allocate more than there is
225  * unprotected memory in A available, and checks
226  * checks that memory.min protects pagecache even
227  * in this case.
228  */
229 static int test_memcg_min(const char *root)
230 {
231         int ret = KSFT_FAIL;
232         char *parent[3] = {NULL};
233         char *children[4] = {NULL};
234         long c[4];
235         int i, attempts;
236         int fd;
237
238         fd = get_temp_fd();
239         if (fd < 0)
240                 goto cleanup;
241
242         parent[0] = cg_name(root, "memcg_test_0");
243         if (!parent[0])
244                 goto cleanup;
245
246         parent[1] = cg_name(parent[0], "memcg_test_1");
247         if (!parent[1])
248                 goto cleanup;
249
250         parent[2] = cg_name(parent[0], "memcg_test_2");
251         if (!parent[2])
252                 goto cleanup;
253
254         if (cg_create(parent[0]))
255                 goto cleanup;
256
257         if (cg_read_long(parent[0], "memory.min")) {
258                 ret = KSFT_SKIP;
259                 goto cleanup;
260         }
261
262         if (cg_write(parent[0], "cgroup.subtree_control", "+memory"))
263                 goto cleanup;
264
265         if (cg_write(parent[0], "memory.max", "200M"))
266                 goto cleanup;
267
268         if (cg_write(parent[0], "memory.swap.max", "0"))
269                 goto cleanup;
270
271         if (cg_create(parent[1]))
272                 goto cleanup;
273
274         if (cg_write(parent[1], "cgroup.subtree_control", "+memory"))
275                 goto cleanup;
276
277         if (cg_create(parent[2]))
278                 goto cleanup;
279
280         for (i = 0; i < ARRAY_SIZE(children); i++) {
281                 children[i] = cg_name_indexed(parent[1], "child_memcg", i);
282                 if (!children[i])
283                         goto cleanup;
284
285                 if (cg_create(children[i]))
286                         goto cleanup;
287
288                 if (i == 2)
289                         continue;
290
291                 cg_run_nowait(children[i], alloc_pagecache_50M_noexit,
292                               (void *)(long)fd);
293         }
294
295         if (cg_write(parent[0], "memory.min", "50M"))
296                 goto cleanup;
297         if (cg_write(parent[1], "memory.min", "50M"))
298                 goto cleanup;
299         if (cg_write(children[0], "memory.min", "75M"))
300                 goto cleanup;
301         if (cg_write(children[1], "memory.min", "25M"))
302                 goto cleanup;
303         if (cg_write(children[2], "memory.min", "500M"))
304                 goto cleanup;
305         if (cg_write(children[3], "memory.min", "0"))
306                 goto cleanup;
307
308         attempts = 0;
309         while (!values_close(cg_read_long(parent[1], "memory.current"),
310                              MB(150), 3)) {
311                 if (attempts++ > 5)
312                         break;
313                 sleep(1);
314         }
315
316         if (cg_run(parent[2], alloc_anon, (void *)MB(148)))
317                 goto cleanup;
318
319         if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
320                 goto cleanup;
321
322         for (i = 0; i < ARRAY_SIZE(children); i++)
323                 c[i] = cg_read_long(children[i], "memory.current");
324
325         if (!values_close(c[0], MB(33), 10))
326                 goto cleanup;
327
328         if (!values_close(c[1], MB(17), 10))
329                 goto cleanup;
330
331         if (!values_close(c[2], 0, 1))
332                 goto cleanup;
333
334         if (!cg_run(parent[2], alloc_anon, (void *)MB(170)))
335                 goto cleanup;
336
337         if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
338                 goto cleanup;
339
340         ret = KSFT_PASS;
341
342 cleanup:
343         for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) {
344                 if (!children[i])
345                         continue;
346
347                 cg_destroy(children[i]);
348                 free(children[i]);
349         }
350
351         for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) {
352                 if (!parent[i])
353                         continue;
354
355                 cg_destroy(parent[i]);
356                 free(parent[i]);
357         }
358         close(fd);
359         return ret;
360 }
361
362 /*
363  * First, this test creates the following hierarchy:
364  * A       memory.low = 50M,  memory.max = 200M
365  * A/B     memory.low = 50M,  memory.current = 50M
366  * A/B/C   memory.low = 75M,  memory.current = 50M
367  * A/B/D   memory.low = 25M,  memory.current = 50M
368  * A/B/E   memory.low = 500M, memory.current = 0
369  * A/B/F   memory.low = 0,    memory.current = 50M
370  *
371  * Usages are pagecache.
372  * Then it creates A/G an creates a significant
373  * memory pressure in it.
374  *
375  * Then it checks actual memory usages and expects that:
376  * A/B    memory.current ~= 50M
377  * A/B/   memory.current ~= 33M
378  * A/B/D  memory.current ~= 17M
379  * A/B/E  memory.current ~= 0
380  *
381  * After that it tries to allocate more than there is
382  * unprotected memory in A available,
383  * and checks low and oom events in memory.events.
384  */
385 static int test_memcg_low(const char *root)
386 {
387         int ret = KSFT_FAIL;
388         char *parent[3] = {NULL};
389         char *children[4] = {NULL};
390         long low, oom;
391         long c[4];
392         int i;
393         int fd;
394
395         fd = get_temp_fd();
396         if (fd < 0)
397                 goto cleanup;
398
399         parent[0] = cg_name(root, "memcg_test_0");
400         if (!parent[0])
401                 goto cleanup;
402
403         parent[1] = cg_name(parent[0], "memcg_test_1");
404         if (!parent[1])
405                 goto cleanup;
406
407         parent[2] = cg_name(parent[0], "memcg_test_2");
408         if (!parent[2])
409                 goto cleanup;
410
411         if (cg_create(parent[0]))
412                 goto cleanup;
413
414         if (cg_read_long(parent[0], "memory.low"))
415                 goto cleanup;
416
417         if (cg_write(parent[0], "cgroup.subtree_control", "+memory"))
418                 goto cleanup;
419
420         if (cg_write(parent[0], "memory.max", "200M"))
421                 goto cleanup;
422
423         if (cg_write(parent[0], "memory.swap.max", "0"))
424                 goto cleanup;
425
426         if (cg_create(parent[1]))
427                 goto cleanup;
428
429         if (cg_write(parent[1], "cgroup.subtree_control", "+memory"))
430                 goto cleanup;
431
432         if (cg_create(parent[2]))
433                 goto cleanup;
434
435         for (i = 0; i < ARRAY_SIZE(children); i++) {
436                 children[i] = cg_name_indexed(parent[1], "child_memcg", i);
437                 if (!children[i])
438                         goto cleanup;
439
440                 if (cg_create(children[i]))
441                         goto cleanup;
442
443                 if (i == 2)
444                         continue;
445
446                 if (cg_run(children[i], alloc_pagecache_50M, (void *)(long)fd))
447                         goto cleanup;
448         }
449
450         if (cg_write(parent[0], "memory.low", "50M"))
451                 goto cleanup;
452         if (cg_write(parent[1], "memory.low", "50M"))
453                 goto cleanup;
454         if (cg_write(children[0], "memory.low", "75M"))
455                 goto cleanup;
456         if (cg_write(children[1], "memory.low", "25M"))
457                 goto cleanup;
458         if (cg_write(children[2], "memory.low", "500M"))
459                 goto cleanup;
460         if (cg_write(children[3], "memory.low", "0"))
461                 goto cleanup;
462
463         if (cg_run(parent[2], alloc_anon, (void *)MB(148)))
464                 goto cleanup;
465
466         if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
467                 goto cleanup;
468
469         for (i = 0; i < ARRAY_SIZE(children); i++)
470                 c[i] = cg_read_long(children[i], "memory.current");
471
472         if (!values_close(c[0], MB(33), 10))
473                 goto cleanup;
474
475         if (!values_close(c[1], MB(17), 10))
476                 goto cleanup;
477
478         if (!values_close(c[2], 0, 1))
479                 goto cleanup;
480
481         if (cg_run(parent[2], alloc_anon, (void *)MB(166))) {
482                 fprintf(stderr,
483                         "memory.low prevents from allocating anon memory\n");
484                 goto cleanup;
485         }
486
487         for (i = 0; i < ARRAY_SIZE(children); i++) {
488                 oom = cg_read_key_long(children[i], "memory.events", "oom ");
489                 low = cg_read_key_long(children[i], "memory.events", "low ");
490
491                 if (oom)
492                         goto cleanup;
493                 if (i < 2 && low <= 0)
494                         goto cleanup;
495                 if (i >= 2 && low)
496                         goto cleanup;
497         }
498
499         ret = KSFT_PASS;
500
501 cleanup:
502         for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) {
503                 if (!children[i])
504                         continue;
505
506                 cg_destroy(children[i]);
507                 free(children[i]);
508         }
509
510         for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) {
511                 if (!parent[i])
512                         continue;
513
514                 cg_destroy(parent[i]);
515                 free(parent[i]);
516         }
517         close(fd);
518         return ret;
519 }
520
521 static int alloc_pagecache_max_30M(const char *cgroup, void *arg)
522 {
523         size_t size = MB(50);
524         int ret = -1;
525         long current;
526         int fd;
527
528         fd = get_temp_fd();
529         if (fd < 0)
530                 return -1;
531
532         if (alloc_pagecache(fd, size))
533                 goto cleanup;
534
535         current = cg_read_long(cgroup, "memory.current");
536         if (current <= MB(29) || current > MB(30))
537                 goto cleanup;
538
539         ret = 0;
540
541 cleanup:
542         close(fd);
543         return ret;
544
545 }
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
558         memcg = cg_name(root, "memcg_test");
559         if (!memcg)
560                 goto cleanup;
561
562         if (cg_create(memcg))
563                 goto cleanup;
564
565         if (cg_read_strcmp(memcg, "memory.high", "max\n"))
566                 goto cleanup;
567
568         if (cg_write(memcg, "memory.swap.max", "0"))
569                 goto cleanup;
570
571         if (cg_write(memcg, "memory.high", "30M"))
572                 goto cleanup;
573
574         if (cg_run(memcg, alloc_anon, (void *)MB(100)))
575                 goto cleanup;
576
577         if (!cg_run(memcg, alloc_pagecache_50M_check, NULL))
578                 goto cleanup;
579
580         if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
581                 goto cleanup;
582
583         high = cg_read_key_long(memcg, "memory.events", "high ");
584         if (high <= 0)
585                 goto cleanup;
586
587         ret = KSFT_PASS;
588
589 cleanup:
590         cg_destroy(memcg);
591         free(memcg);
592
593         return ret;
594 }
595
596 /*
597  * This test checks that memory.max limits the amount of
598  * memory which can be consumed by either anonymous memory
599  * or pagecache.
600  */
601 static int test_memcg_max(const char *root)
602 {
603         int ret = KSFT_FAIL;
604         char *memcg;
605         long current, max;
606
607         memcg = cg_name(root, "memcg_test");
608         if (!memcg)
609                 goto cleanup;
610
611         if (cg_create(memcg))
612                 goto cleanup;
613
614         if (cg_read_strcmp(memcg, "memory.max", "max\n"))
615                 goto cleanup;
616
617         if (cg_write(memcg, "memory.swap.max", "0"))
618                 goto cleanup;
619
620         if (cg_write(memcg, "memory.max", "30M"))
621                 goto cleanup;
622
623         /* Should be killed by OOM killer */
624         if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
625                 goto cleanup;
626
627         if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
628                 goto cleanup;
629
630         current = cg_read_long(memcg, "memory.current");
631         if (current > MB(30) || !current)
632                 goto cleanup;
633
634         max = cg_read_key_long(memcg, "memory.events", "max ");
635         if (max <= 0)
636                 goto cleanup;
637
638         ret = KSFT_PASS;
639
640 cleanup:
641         cg_destroy(memcg);
642         free(memcg);
643
644         return ret;
645 }
646
647 static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
648 {
649         long mem_max = (long)arg;
650         size_t size = MB(50);
651         char *buf, *ptr;
652         long mem_current, swap_current;
653         int ret = -1;
654
655         buf = malloc(size);
656         for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
657                 *ptr = 0;
658
659         mem_current = cg_read_long(cgroup, "memory.current");
660         if (!mem_current || !values_close(mem_current, mem_max, 3))
661                 goto cleanup;
662
663         swap_current = cg_read_long(cgroup, "memory.swap.current");
664         if (!swap_current ||
665             !values_close(mem_current + swap_current, size, 3))
666                 goto cleanup;
667
668         ret = 0;
669 cleanup:
670         free(buf);
671         return ret;
672 }
673
674 /*
675  * This test checks that memory.swap.max limits the amount of
676  * anonymous memory which can be swapped out.
677  */
678 static int test_memcg_swap_max(const char *root)
679 {
680         int ret = KSFT_FAIL;
681         char *memcg;
682         long max;
683
684         if (!is_swap_enabled())
685                 return KSFT_SKIP;
686
687         memcg = cg_name(root, "memcg_test");
688         if (!memcg)
689                 goto cleanup;
690
691         if (cg_create(memcg))
692                 goto cleanup;
693
694         if (cg_read_long(memcg, "memory.swap.current")) {
695                 ret = KSFT_SKIP;
696                 goto cleanup;
697         }
698
699         if (cg_read_strcmp(memcg, "memory.max", "max\n"))
700                 goto cleanup;
701
702         if (cg_read_strcmp(memcg, "memory.swap.max", "max\n"))
703                 goto cleanup;
704
705         if (cg_write(memcg, "memory.swap.max", "30M"))
706                 goto cleanup;
707
708         if (cg_write(memcg, "memory.max", "30M"))
709                 goto cleanup;
710
711         /* Should be killed by OOM killer */
712         if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
713                 goto cleanup;
714
715         if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
716                 goto cleanup;
717
718         if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
719                 goto cleanup;
720
721         if (cg_run(memcg, alloc_anon_50M_check_swap, (void *)MB(30)))
722                 goto cleanup;
723
724         max = cg_read_key_long(memcg, "memory.events", "max ");
725         if (max <= 0)
726                 goto cleanup;
727
728         ret = KSFT_PASS;
729
730 cleanup:
731         cg_destroy(memcg);
732         free(memcg);
733
734         return ret;
735 }
736
737 /*
738  * This test disables swapping and tries to allocate anonymous memory
739  * up to OOM. Then it checks for oom and oom_kill events in
740  * memory.events.
741  */
742 static int test_memcg_oom_events(const char *root)
743 {
744         int ret = KSFT_FAIL;
745         char *memcg;
746
747         memcg = cg_name(root, "memcg_test");
748         if (!memcg)
749                 goto cleanup;
750
751         if (cg_create(memcg))
752                 goto cleanup;
753
754         if (cg_write(memcg, "memory.max", "30M"))
755                 goto cleanup;
756
757         if (cg_write(memcg, "memory.swap.max", "0"))
758                 goto cleanup;
759
760         if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
761                 goto cleanup;
762
763         if (cg_read_strcmp(memcg, "cgroup.procs", ""))
764                 goto cleanup;
765
766         if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
767                 goto cleanup;
768
769         if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
770                 goto cleanup;
771
772         ret = KSFT_PASS;
773
774 cleanup:
775         cg_destroy(memcg);
776         free(memcg);
777
778         return ret;
779 }
780
781 struct tcp_server_args {
782         unsigned short port;
783         int ctl[2];
784 };
785
786 static int tcp_server(const char *cgroup, void *arg)
787 {
788         struct tcp_server_args *srv_args = arg;
789         struct sockaddr_in6 saddr = { 0 };
790         socklen_t slen = sizeof(saddr);
791         int sk, client_sk, ctl_fd, yes = 1, ret = -1;
792
793         close(srv_args->ctl[0]);
794         ctl_fd = srv_args->ctl[1];
795
796         saddr.sin6_family = AF_INET6;
797         saddr.sin6_addr = in6addr_any;
798         saddr.sin6_port = htons(srv_args->port);
799
800         sk = socket(AF_INET6, SOCK_STREAM, 0);
801         if (sk < 0)
802                 return ret;
803
804         if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
805                 goto cleanup;
806
807         if (bind(sk, (struct sockaddr *)&saddr, slen)) {
808                 write(ctl_fd, &errno, sizeof(errno));
809                 goto cleanup;
810         }
811
812         if (listen(sk, 1))
813                 goto cleanup;
814
815         ret = 0;
816         if (write(ctl_fd, &ret, sizeof(ret)) != sizeof(ret)) {
817                 ret = -1;
818                 goto cleanup;
819         }
820
821         client_sk = accept(sk, NULL, NULL);
822         if (client_sk < 0)
823                 goto cleanup;
824
825         ret = -1;
826         for (;;) {
827                 uint8_t buf[0x100000];
828
829                 if (write(client_sk, buf, sizeof(buf)) <= 0) {
830                         if (errno == ECONNRESET)
831                                 ret = 0;
832                         break;
833                 }
834         }
835
836         close(client_sk);
837
838 cleanup:
839         close(sk);
840         return ret;
841 }
842
843 static int tcp_client(const char *cgroup, unsigned short port)
844 {
845         const char server[] = "localhost";
846         struct addrinfo *ai;
847         char servport[6];
848         int retries = 0x10; /* nice round number */
849         int sk, ret;
850
851         snprintf(servport, sizeof(servport), "%hd", port);
852         ret = getaddrinfo(server, servport, NULL, &ai);
853         if (ret)
854                 return ret;
855
856         sk = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
857         if (sk < 0)
858                 goto free_ainfo;
859
860         ret = connect(sk, ai->ai_addr, ai->ai_addrlen);
861         if (ret < 0)
862                 goto close_sk;
863
864         ret = KSFT_FAIL;
865         while (retries--) {
866                 uint8_t buf[0x100000];
867                 long current, sock;
868
869                 if (read(sk, buf, sizeof(buf)) <= 0)
870                         goto close_sk;
871
872                 current = cg_read_long(cgroup, "memory.current");
873                 sock = cg_read_key_long(cgroup, "memory.stat", "sock ");
874
875                 if (current < 0 || sock < 0)
876                         goto close_sk;
877
878                 if (current < sock)
879                         goto close_sk;
880
881                 if (values_close(current, sock, 10)) {
882                         ret = KSFT_PASS;
883                         break;
884                 }
885         }
886
887 close_sk:
888         close(sk);
889 free_ainfo:
890         freeaddrinfo(ai);
891         return ret;
892 }
893
894 /*
895  * This test checks socket memory accounting.
896  * The test forks a TCP server listens on a random port between 1000
897  * and 61000. Once it gets a client connection, it starts writing to
898  * its socket.
899  * The TCP client interleaves reads from the socket with check whether
900  * memory.current and memory.stat.sock are similar.
901  */
902 static int test_memcg_sock(const char *root)
903 {
904         int bind_retries = 5, ret = KSFT_FAIL, pid, err;
905         unsigned short port;
906         char *memcg;
907
908         memcg = cg_name(root, "memcg_test");
909         if (!memcg)
910                 goto cleanup;
911
912         if (cg_create(memcg))
913                 goto cleanup;
914
915         while (bind_retries--) {
916                 struct tcp_server_args args;
917
918                 if (pipe(args.ctl))
919                         goto cleanup;
920
921                 port = args.port = 1000 + rand() % 60000;
922
923                 pid = cg_run_nowait(memcg, tcp_server, &args);
924                 if (pid < 0)
925                         goto cleanup;
926
927                 close(args.ctl[1]);
928                 if (read(args.ctl[0], &err, sizeof(err)) != sizeof(err))
929                         goto cleanup;
930                 close(args.ctl[0]);
931
932                 if (!err)
933                         break;
934                 if (err != EADDRINUSE)
935                         goto cleanup;
936
937                 waitpid(pid, NULL, 0);
938         }
939
940         if (err == EADDRINUSE) {
941                 ret = KSFT_SKIP;
942                 goto cleanup;
943         }
944
945         if (tcp_client(memcg, port) != KSFT_PASS)
946                 goto cleanup;
947
948         waitpid(pid, &err, 0);
949         if (WEXITSTATUS(err))
950                 goto cleanup;
951
952         if (cg_read_long(memcg, "memory.current") < 0)
953                 goto cleanup;
954
955         if (cg_read_key_long(memcg, "memory.stat", "sock "))
956                 goto cleanup;
957
958         ret = KSFT_PASS;
959
960 cleanup:
961         cg_destroy(memcg);
962         free(memcg);
963
964         return ret;
965 }
966
967 #define T(x) { x, #x }
968 struct memcg_test {
969         int (*fn)(const char *root);
970         const char *name;
971 } tests[] = {
972         T(test_memcg_subtree_control),
973         T(test_memcg_current),
974         T(test_memcg_min),
975         T(test_memcg_low),
976         T(test_memcg_high),
977         T(test_memcg_max),
978         T(test_memcg_oom_events),
979         T(test_memcg_swap_max),
980         T(test_memcg_sock),
981 };
982 #undef T
983
984 int main(int argc, char **argv)
985 {
986         char root[PATH_MAX];
987         int i, ret = EXIT_SUCCESS;
988
989         if (cg_find_unified_root(root, sizeof(root)))
990                 ksft_exit_skip("cgroup v2 isn't mounted\n");
991
992         /*
993          * Check that memory controller is available:
994          * memory is listed in cgroup.controllers
995          */
996         if (cg_read_strstr(root, "cgroup.controllers", "memory"))
997                 ksft_exit_skip("memory controller isn't available\n");
998
999         for (i = 0; i < ARRAY_SIZE(tests); i++) {
1000                 switch (tests[i].fn(root)) {
1001                 case KSFT_PASS:
1002                         ksft_test_result_pass("%s\n", tests[i].name);
1003                         break;
1004                 case KSFT_SKIP:
1005                         ksft_test_result_skip("%s\n", tests[i].name);
1006                         break;
1007                 default:
1008                         ret = EXIT_FAILURE;
1009                         ksft_test_result_fail("%s\n", tests[i].name);
1010                         break;
1011                 }
1012         }
1013
1014         return ret;
1015 }