module: add concurrency limiter
The patch "module: avoid allocation if module is already present and ready"
does the work to mitigate stupid vmallocs for the final module. However,
a pretty silly overlooked thing is that we *also* *always* vmalloc for
each and every single system call on finit_module() due to the call
kernel_read_file_from_fd().
The Linux kernel module auto-loader, kmod, already has its own
concurrency limiter but to allow only 50 concurrent modprobe
requests out to userspace. And they're allowed to only all last max
5 seconds. As soon as any new modprobe call finishes though a new
modprobe is allowed. So in theory this path still allows a lot of
concurrent finit_module() calls.
Userspace can also be stupid, and if they don't check if a module exists
prior to calling finit_module, or if things happens to race, we could end
up with many kernel_read_file_from_fd() calls thrashing vmap space too.
Using stress-ng's new module ops we can replicate a stupid kernel or
userspace. The vmap issues for examples originally reported by David
Hildenbrand on a 400 CPU system can be easily reproduced with the
following:
./stress-ng --module 100 --module-name xfs
XXX: add value
With this patch we lower top memory consumption further to XXX than we did
with our last patch, now providing a limiter on the kread part. The
magic value of 20 is purely empirical for now. We don't keep the
count until the module is loaded as that would add tons of possible
deadlock races.
In theory other places where vmap space is contended from userspace
*could* still exist, but we can address those as we we evolve from
this simple limiter step on the clear case where we do see this
happening even on bootup with a large CPU count system.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
1 file changed