The module_attach test contains subtests which check that unloading a
module while there are BPF programs attached to its functions is not
possible because the module is still referenced.
The problem is that the test calls the generic unload_module() helper
function which is used for module cleanup after test_progs terminate and
tries to wait until all module references are released. This
unnecessarily slows down the module_attach subtests since each
unsuccessful call to unload_module() takes about 1 second.
Introduce try_unload_module() which takes the number of retries as a
parameter. Make unload_module() call it with the currently used amount
of 10000 retries but call it with just 1 retry from module_attach tests
as it is always expected to fail. This speeds up the module_attach()
test significantly.
Before:
# time ./test_progs -t module_attach
[...]
Summary: 1/14 PASSED, 0 SKIPPED, 0 FAILED
real 0m5.011s
user 0m0.293s
sys 0m0.108s
After:
# time ./test_progs -t module_attach
[...]
Summary: 1/14 PASSED, 0 SKIPPED, 0 FAILED
real 0m0.350s
user 0m0.197s
sys 0m0.063s
Signed-off-by: Viktor Malik <vmalik@redhat.com>
Reviewed-by: Alan Maguire <alan.maguire@oracle.com>
Tested-by: Alan Maguire <alan.maguire@oracle.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260306101628.3822284-1-vmalik@redhat.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
if (!ASSERT_OK_PTR(link, "module_attach attach"))
goto cleanup;
- ASSERT_ERR(unload_bpf_testmod(false), "unload_bpf_testmod");
+ ASSERT_ERR(try_unload_module("bpf_testmod", 1, false), "try_unload_module");
bpf_link__destroy(link);
cleanup:
test_module_attach__destroy(skel);
return syscall(__NR_delete_module, name, flags);
}
-int unload_module(const char *name, bool verbose)
+int try_unload_module(const char *name, int retries, bool verbose)
{
int ret, cnt = 0;
ret = delete_module(name, 0);
if (!ret || errno != EAGAIN)
break;
- if (++cnt > 10000) {
+ if (++cnt > retries) {
fprintf(stdout, "Unload of %s timed out\n", name);
break;
}
return 0;
}
+int unload_module(const char *name, bool verbose)
+{
+ return try_unload_module(name, 10000, verbose);
+}
+
static int __load_module(const char *path, const char *param_values, bool verbose)
{
int fd;
int delete_module(const char *name, int flags);
int load_module(const char *path, bool verbose);
int load_module_params(const char *path, const char *param_values, bool verbose);
+int try_unload_module(const char *name, int retries, bool verbose);
int unload_module(const char *name, bool verbose);
static inline __u64 get_time_ns(void)