summaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez2017-06-23 21:19:12 +0200
committerJessica Yu2017-06-27 19:36:31 +0200
commit165d1cc0074b2f938586274776d029b9bce914c4 (patch)
tree425de224521ec588638633c2b33de8c1169d331b /kernel/module.c
parentmodule: use list_for_each_entry_rcu() on find_module_all() (diff)
downloadkernel-qcow2-linux-165d1cc0074b2f938586274776d029b9bce914c4.tar.gz
kernel-qcow2-linux-165d1cc0074b2f938586274776d029b9bce914c4.tar.xz
kernel-qcow2-linux-165d1cc0074b2f938586274776d029b9bce914c4.zip
kmod: reduce atomic operations on kmod_concurrent and simplify
When checking if we want to allow a kmod thread to kick off we increment, then read to see if we should enable a thread. If we were over the allowed limit limit we decrement. Splitting the increment far apart from decrement means there could be a time where two increments happen potentially giving a false failure on a thread which should have been allowed. CPU1 CPU2 atomic_inc() atomic_inc() atomic_read() atomic_read() atomic_dec() atomic_dec() In this case a read on CPU1 gets the atomic_inc()'s and we could negate it from getting a kmod thread. We could try to prevent this with a lock or preemption but that is overkill. We can fix by reducing the number of atomic operations. We do this by inverting the logic of of the enabler, instead of incrementing kmod_concurrent as we get new kmod users, define the variable kmod_concurrent_max as the max number of currently allowed kmod users and as we get new kmod users just decrement it if its still positive. This combines the dec and read in one atomic operation. In this case we no longer get the same false failure: CPU1 CPU2 atomic_dec_if_positive() atomic_dec_if_positive() atomic_inc() atomic_inc() The number of threads is computed at init, and since the current computation of kmod_concurrent includes the thread count we can avoid setting kmod_concurrent_max later in boot through an init call by simply sticking to 50 as the kmod_concurrent_max. The assumption here is a system with modules must at least have ~16 MiB of RAM. Suggested-by: Petr Mladek <pmladek@suse.com> Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org> Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Jessica Yu <jeyu@kernel.org>
Diffstat (limited to 'kernel/module.c')
0 files changed, 0 insertions, 0 deletions