Re: [PATCH v2 bpf-next 4/4] selftests/bpf: add auto-detach test
On 5/23/19 10:58 AM, Roman Gushchin wrote: > On Wed, May 22, 2019 at 10:47:24PM -0700, Yonghong Song wrote: >> >> >> On 5/22/19 4:20 PM, Roman Gushchin wrote: >>> Add a kselftest to cover bpf auto-detachment functionality. >>> The test creates a cgroup, associates some resources with it, >>> attaches a couple of bpf programs and deletes the cgroup. >>> >>> Then it checks that bpf programs are going away in 5 seconds. >>> >>> Expected output: >>> $ ./test_cgroup_attach >>> #override:PASS >>> #multi:PASS >>> #autodetach:PASS >>> test_cgroup_attach:PASS >>> >>> On a kernel without auto-detaching: >>> $ ./test_cgroup_attach >>> #override:PASS >>> #multi:PASS >>> #autodetach:FAIL >>> test_cgroup_attach:FAIL >> >> I ran this problem without both old and new kernels and >> both get all PASSes. My testing environment is a VM. >> Could you specify how to trigger the above failure? > > Most likely you're running cgroup v1, so the memory controller > is not enabled on unified hierarchy. You need to pass > "cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1" > as boot time options to run fully on cgroup v2. I tested on a cgroup v2 machine and it indeed failed without the core patch. Thanks! > > But generally speaking, the lifecycle of a dying cgroup is > completely implementation-defined. No guarantees are provided. > So false positives are fine here, and shouldn't be considered as > something bad. > > At the end all we want it to detach programs in a reasonable time > after rmdir. > > Btw, thank you for the careful review of the patchset. I'll > address your comments, add acks and will send out v3. > > Thanks! >
Re: [PATCH v2 bpf-next 4/4] selftests/bpf: add auto-detach test
On Wed, May 22, 2019 at 10:47:24PM -0700, Yonghong Song wrote: > > > On 5/22/19 4:20 PM, Roman Gushchin wrote: > > Add a kselftest to cover bpf auto-detachment functionality. > > The test creates a cgroup, associates some resources with it, > > attaches a couple of bpf programs and deletes the cgroup. > > > > Then it checks that bpf programs are going away in 5 seconds. > > > > Expected output: > >$ ./test_cgroup_attach > >#override:PASS > >#multi:PASS > >#autodetach:PASS > >test_cgroup_attach:PASS > > > > On a kernel without auto-detaching: > >$ ./test_cgroup_attach > >#override:PASS > >#multi:PASS > >#autodetach:FAIL > >test_cgroup_attach:FAIL > > I ran this problem without both old and new kernels and > both get all PASSes. My testing environment is a VM. > Could you specify how to trigger the above failure? Most likely you're running cgroup v1, so the memory controller is not enabled on unified hierarchy. You need to pass "cgroup_no_v1=all systemd.unified_cgroup_hierarchy=1" as boot time options to run fully on cgroup v2. But generally speaking, the lifecycle of a dying cgroup is completely implementation-defined. No guarantees are provided. So false positives are fine here, and shouldn't be considered as something bad. At the end all we want it to detach programs in a reasonable time after rmdir. Btw, thank you for the careful review of the patchset. I'll address your comments, add acks and will send out v3. Thanks!
Re: [PATCH v2 bpf-next 4/4] selftests/bpf: add auto-detach test
On 5/22/19 4:20 PM, Roman Gushchin wrote: > Add a kselftest to cover bpf auto-detachment functionality. > The test creates a cgroup, associates some resources with it, > attaches a couple of bpf programs and deletes the cgroup. > > Then it checks that bpf programs are going away in 5 seconds. > > Expected output: >$ ./test_cgroup_attach >#override:PASS >#multi:PASS >#autodetach:PASS >test_cgroup_attach:PASS > > On a kernel without auto-detaching: >$ ./test_cgroup_attach >#override:PASS >#multi:PASS >#autodetach:FAIL >test_cgroup_attach:FAIL > > Signed-off-by: Roman Gushchin > --- > .../selftests/bpf/test_cgroup_attach.c| 99 ++- > 1 file changed, 98 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/bpf/test_cgroup_attach.c > b/tools/testing/selftests/bpf/test_cgroup_attach.c > index 93d4fe295e7d..bc5bd0f1728e 100644 > --- a/tools/testing/selftests/bpf/test_cgroup_attach.c > +++ b/tools/testing/selftests/bpf/test_cgroup_attach.c > @@ -456,9 +456,106 @@ static int test_multiprog(void) > return rc; > } > > +static int test_autodetach(void) > +{ > + __u32 prog_cnt = 4, attach_flags; > + int allow_prog[2] = {0}; > + __u32 prog_ids[2] = {0}; > + int cg = 0, i, rc = -1; > + void *ptr = NULL; > + int attempts; > + > + Also extra line here. > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + allow_prog[i] = prog_load_cnt(1, 1 << i); > + if (!allow_prog[i]) > + goto err; > + } > + > + if (setup_cgroup_environment()) > + goto err; > + > + /* create a cgroup, attach two programs and remember their ids */ > + cg = create_and_get_cgroup("/cg_autodetach"); [...] > + > int main(int argc, char **argv) > { > - int (*tests[])(void) = {test_foo_bar, test_multiprog}; > + int (*tests[])(void) = { > + test_foo_bar, > + test_multiprog, > + test_autodetach, > + }; > int errors = 0; > int i; > >
Re: [PATCH v2 bpf-next 4/4] selftests/bpf: add auto-detach test
On 5/22/19 4:20 PM, Roman Gushchin wrote: > Add a kselftest to cover bpf auto-detachment functionality. > The test creates a cgroup, associates some resources with it, > attaches a couple of bpf programs and deletes the cgroup. > > Then it checks that bpf programs are going away in 5 seconds. > > Expected output: >$ ./test_cgroup_attach >#override:PASS >#multi:PASS >#autodetach:PASS >test_cgroup_attach:PASS > > On a kernel without auto-detaching: >$ ./test_cgroup_attach >#override:PASS >#multi:PASS >#autodetach:FAIL >test_cgroup_attach:FAIL I ran this problem without both old and new kernels and both get all PASSes. My testing environment is a VM. Could you specify how to trigger the above failure? > > Signed-off-by: Roman Gushchin > --- > .../selftests/bpf/test_cgroup_attach.c| 99 ++- > 1 file changed, 98 insertions(+), 1 deletion(-) > > diff --git a/tools/testing/selftests/bpf/test_cgroup_attach.c > b/tools/testing/selftests/bpf/test_cgroup_attach.c > index 93d4fe295e7d..bc5bd0f1728e 100644 > --- a/tools/testing/selftests/bpf/test_cgroup_attach.c > +++ b/tools/testing/selftests/bpf/test_cgroup_attach.c > @@ -456,9 +456,106 @@ static int test_multiprog(void) > return rc; > } > > +static int test_autodetach(void) > +{ > + __u32 prog_cnt = 4, attach_flags; > + int allow_prog[2] = {0}; > + __u32 prog_ids[2] = {0}; > + int cg = 0, i, rc = -1; > + void *ptr = NULL; > + int attempts; > + > + > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + allow_prog[i] = prog_load_cnt(1, 1 << i); > + if (!allow_prog[i]) > + goto err; > + } > + > + if (setup_cgroup_environment()) > + goto err; > + > + /* create a cgroup, attach two programs and remember their ids */ > + cg = create_and_get_cgroup("/cg_autodetach"); > + if (cg < 0) > + goto err; > + > + if (join_cgroup("/cg_autodetach")) > + goto err; > + > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + if (bpf_prog_attach(allow_prog[i], cg, BPF_CGROUP_INET_EGRESS, > + BPF_F_ALLOW_MULTI)) { > + log_err("Attaching prog[%d] to cg:egress", i); > + goto err; > + } > + } > + > + /* make sure that programs are attached and run some traffic */ > + assert(bpf_prog_query(cg, BPF_CGROUP_INET_EGRESS, 0, _flags, > + prog_ids, _cnt) == 0); > + assert(system(PING_CMD) == 0); > + > + /* allocate some memory (4Mb) to pin the original cgroup */ > + ptr = malloc(4 * (1 << 20)); > + if (!ptr) > + goto err; > + > + /* close programs and cgroup fd */ > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { > + close(allow_prog[i]); > + allow_prog[i] = 0; > + } > + > + close(cg); > + cg = 0; > + > + /* leave the cgroup and remove it. don't detach programs */ > + cleanup_cgroup_environment(); > + > + /* wait for the asynchronous auto-detachment. > + * wait for no more than 5 sec and give up. > + */ > + for (i = 0; i < ARRAY_SIZE(prog_ids); i++) { > + for (attempts = 5; attempts >= 0; attempts--) { > + int fd = bpf_prog_get_fd_by_id(prog_ids[i]); > + > + if (fd < 0) > + break; > + > + /* don't leave the fd open */ > + close(fd); > + > + if (!attempts) > + goto err; > + > + sleep(1); > + } > + } > + > + rc = 0; > +err: > + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) > + if (allow_prog[i] > 0) > + close(allow_prog[i]); > + if (cg) > + close(cg); > + free(ptr); > + cleanup_cgroup_environment(); > + if (!rc) > + printf("#autodetach:PASS\n"); > + else > + printf("#autodetach:FAIL\n"); > + return rc; > +} > + > int main(int argc, char **argv) > { > - int (*tests[])(void) = {test_foo_bar, test_multiprog}; > + int (*tests[])(void) = { > + test_foo_bar, > + test_multiprog, > + test_autodetach, > + }; > int errors = 0; > int i; > >
[PATCH v2 bpf-next 4/4] selftests/bpf: add auto-detach test
Add a kselftest to cover bpf auto-detachment functionality. The test creates a cgroup, associates some resources with it, attaches a couple of bpf programs and deletes the cgroup. Then it checks that bpf programs are going away in 5 seconds. Expected output: $ ./test_cgroup_attach #override:PASS #multi:PASS #autodetach:PASS test_cgroup_attach:PASS On a kernel without auto-detaching: $ ./test_cgroup_attach #override:PASS #multi:PASS #autodetach:FAIL test_cgroup_attach:FAIL Signed-off-by: Roman Gushchin --- .../selftests/bpf/test_cgroup_attach.c| 99 ++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/bpf/test_cgroup_attach.c b/tools/testing/selftests/bpf/test_cgroup_attach.c index 93d4fe295e7d..bc5bd0f1728e 100644 --- a/tools/testing/selftests/bpf/test_cgroup_attach.c +++ b/tools/testing/selftests/bpf/test_cgroup_attach.c @@ -456,9 +456,106 @@ static int test_multiprog(void) return rc; } +static int test_autodetach(void) +{ + __u32 prog_cnt = 4, attach_flags; + int allow_prog[2] = {0}; + __u32 prog_ids[2] = {0}; + int cg = 0, i, rc = -1; + void *ptr = NULL; + int attempts; + + + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { + allow_prog[i] = prog_load_cnt(1, 1 << i); + if (!allow_prog[i]) + goto err; + } + + if (setup_cgroup_environment()) + goto err; + + /* create a cgroup, attach two programs and remember their ids */ + cg = create_and_get_cgroup("/cg_autodetach"); + if (cg < 0) + goto err; + + if (join_cgroup("/cg_autodetach")) + goto err; + + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { + if (bpf_prog_attach(allow_prog[i], cg, BPF_CGROUP_INET_EGRESS, + BPF_F_ALLOW_MULTI)) { + log_err("Attaching prog[%d] to cg:egress", i); + goto err; + } + } + + /* make sure that programs are attached and run some traffic */ + assert(bpf_prog_query(cg, BPF_CGROUP_INET_EGRESS, 0, _flags, + prog_ids, _cnt) == 0); + assert(system(PING_CMD) == 0); + + /* allocate some memory (4Mb) to pin the original cgroup */ + ptr = malloc(4 * (1 << 20)); + if (!ptr) + goto err; + + /* close programs and cgroup fd */ + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) { + close(allow_prog[i]); + allow_prog[i] = 0; + } + + close(cg); + cg = 0; + + /* leave the cgroup and remove it. don't detach programs */ + cleanup_cgroup_environment(); + + /* wait for the asynchronous auto-detachment. +* wait for no more than 5 sec and give up. +*/ + for (i = 0; i < ARRAY_SIZE(prog_ids); i++) { + for (attempts = 5; attempts >= 0; attempts--) { + int fd = bpf_prog_get_fd_by_id(prog_ids[i]); + + if (fd < 0) + break; + + /* don't leave the fd open */ + close(fd); + + if (!attempts) + goto err; + + sleep(1); + } + } + + rc = 0; +err: + for (i = 0; i < ARRAY_SIZE(allow_prog); i++) + if (allow_prog[i] > 0) + close(allow_prog[i]); + if (cg) + close(cg); + free(ptr); + cleanup_cgroup_environment(); + if (!rc) + printf("#autodetach:PASS\n"); + else + printf("#autodetach:FAIL\n"); + return rc; +} + int main(int argc, char **argv) { - int (*tests[])(void) = {test_foo_bar, test_multiprog}; + int (*tests[])(void) = { + test_foo_bar, + test_multiprog, + test_autodetach, + }; int errors = 0; int i; -- 2.20.1