Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1677242 > unrolled thread

[PATCH v4 0/3] kmod: help make deterministic

Started by"Luis R. Rodriguez" <mcgrof@kernel.org>
First post2017-06-29 00:40 +0200
Last post2017-06-29 00:40 +0200
Articles 3 — 1 participant

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v4 0/3] kmod: help make deterministic "Luis R. Rodriguez" <mcgrof@kernel.org> - 2017-06-29 00:40 +0200
    [PATCH v4 1/3] MAINTAINERS: give kmod some maintainer love "Luis R. Rodriguez" <mcgrof@kernel.org> - 2017-06-29 00:40 +0200
    [PATCH v4 3/3] kmod: throttle kmod thread limit "Luis R. Rodriguez" <mcgrof@kernel.org> - 2017-06-29 00:40 +0200

#1677242 — [PATCH v4 0/3] kmod: help make deterministic

From"Luis R. Rodriguez" <mcgrof@kernel.org>
Date2017-06-29 00:40 +0200
Subject[PATCH v4 0/3] kmod: help make deterministic
Message-ID<tXtMR-16a-5@gated-at.bofh.it>
Andrew,

I'm submitting the last few patches of my kmod series through your tree and as
suggested by Jessica I am picking up maintenance on kmod. These last changes
can either wait until the next release or can be merged now provided someone
reviews the kmod test driver and the merge conflict is addressed with Jessica's
tree with the kmod patch she picked up.

This v4 moves back again from swait to regular waitqueue as suggested generally
by Linus as swait is very specialized [0], and it also drops two patches picked
up by Jessica. Jessica picked the following two patches visible on linux-next
tag next-20170628 as follows:

165d1cc0074b kmod: reduce atomic operations on kmod_concurrent and simplify
93437353daef module: use list_for_each_entry_rcu() on find_module_all()

FWIW, the swait --> wait change proved to just help speed up tests only
marginally, even over a spread of tests these results were generally
consistent. Figured some peformance folks might be interested in that tidbit,
should they wish to go play.

With wait:

time ./kmod.sh -t 0008
real    0m16.366s
user    0m0.883s
sys     0m8.916s

time ./kmod.sh -t 0009
real    0m50.803s
user    0m0.791s
sys     0m9.852s
                                                                               
With swait: 

time ./kmod.sh -t 0008
real    0m16.523s
user    0m0.879s
sys     0m8.977s

time ./kmod.sh -t 0009
real    0m51.258s
user    0m0.812s
sys     0m10.133s

If anyone wants these in a git tree you can check out the 20170628-kmod-only
branch from my linux-next tree [1], based on next-20170628. If there are any
questions or issues please let me know.

[0] https://marc.info/?l=linux-kernel&m=149851347228696&w=2
[1] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20170628-kmod-only

Luis R. Rodriguez (3):
  MAINTAINERS: give kmod some maintainer love
  kmod: add test driver to stress test the module loader
  kmod: throttle kmod thread limit

 MAINTAINERS                           |    9 +
 kernel/kmod.c                         |   16 +-
 lib/Kconfig.debug                     |   25 +
 lib/Makefile                          |    1 +
 lib/test_kmod.c                       | 1246 +++++++++++++++++++++++++++++++++
 tools/testing/selftests/kmod/Makefile |   11 +
 tools/testing/selftests/kmod/config   |    7 +
 tools/testing/selftests/kmod/kmod.sh  |  615 ++++++++++++++++
 8 files changed, 1921 insertions(+), 9 deletions(-)
 create mode 100644 lib/test_kmod.c
 create mode 100644 tools/testing/selftests/kmod/Makefile
 create mode 100644 tools/testing/selftests/kmod/config
 create mode 100755 tools/testing/selftests/kmod/kmod.sh

-- 
2.11.0

[toc] | [next] | [standalone]


#1677244 — [PATCH v4 1/3] MAINTAINERS: give kmod some maintainer love

From"Luis R. Rodriguez" <mcgrof@kernel.org>
Date2017-06-29 00:40 +0200
Subject[PATCH v4 1/3] MAINTAINERS: give kmod some maintainer love
Message-ID<tXtMS-16a-19@gated-at.bofh.it>
In reply to#1677242
As suggested by Jessica, I've been actively working on kmod, so
might as well reflect its maintained status.

Changes are expected to go through akpm's tree.

Cc: Jessica Yu <jeyu@redhat.com>
Suggested-by: Jessica Yu <jeyu@redhat.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index aab3ae5aa12c..d9f5d8687cc1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7561,6 +7561,13 @@ F:	include/linux/kmemleak.h
 F:	mm/kmemleak.c
 F:	mm/kmemleak-test.c
 
+KMOD MODULE USERMODE HELPER
+M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	kernel/kmod.c
+F:	include/linux/kmod.h
+
 KPROBES
 M:	Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
 M:	Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1677248 — [PATCH v4 3/3] kmod: throttle kmod thread limit

From"Luis R. Rodriguez" <mcgrof@kernel.org>
Date2017-06-29 00:40 +0200
Subject[PATCH v4 3/3] kmod: throttle kmod thread limit
Message-ID<tXtMS-16a-25@gated-at.bofh.it>
In reply to#1677242
If we reach the limit of modprobe_limit threads running the next
request_module() call will fail. The original reason for adding
a kill was to do away with possible issues with in old circumstances
which would create a recursive series of request_module() calls.

We can do better than just be super aggressive and reject calls
once we've reached the limit by simply making pending callers wait
until the threshold has been reduced, and then throttling them in,
one by one.

This throttling enables requests over the kmod concurrent limit to
be processed once a pending request completes. Only the first item
queued up to wait is woken up. The assumption here is once a task
is woken it will have no other option to also kick the queue to check
if there are more pending tasks -- regardless of whether or not it
was successful.

By throttling and processing only max kmod concurrent tasks we ensure
we avoid unexpected fatal request_module() calls, and we keep memory
consumption on module loading to a minimum.

With x86_64 qemu, with 4 cores, 4 GiB of RAM it takes the following run
time to run both tests:

time ./kmod.sh -t 0008
real    0m16.366s
user    0m0.883s
sys     0m8.916s

time ./kmod.sh -t 0009
real    0m50.803s
user    0m0.791s
sys     0m9.852s

Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 kernel/kmod.c                        | 16 +++++++---------
 tools/testing/selftests/kmod/kmod.sh | 24 ++----------------------
 2 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/kernel/kmod.c b/kernel/kmod.c
index ff68198fe83b..6d016c5d97c8 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -68,6 +68,7 @@ static DECLARE_RWSEM(umhelper_sem);
  */
 #define MAX_KMOD_CONCURRENT 50
 static atomic_t kmod_concurrent_max = ATOMIC_INIT(MAX_KMOD_CONCURRENT);
+static DECLARE_WAIT_QUEUE_HEAD(kmod_wq);
 
 /*
 	modprobe_path is set via /proc/sys.
@@ -140,7 +141,6 @@ int __request_module(bool wait, const char *fmt, ...)
 	va_list args;
 	char module_name[MODULE_NAME_LEN];
 	int ret;
-	static int kmod_loop_msg;
 
 	/*
 	 * We don't allow synchronous module loading from async.  Module
@@ -164,14 +164,11 @@ int __request_module(bool wait, const char *fmt, ...)
 		return ret;
 
 	if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) {
-		/* We may be blaming an innocent here, but unlikely */
-		if (kmod_loop_msg < 5) {
-			printk(KERN_ERR
-			       "request_module: runaway loop modprobe %s\n",
-			       module_name);
-			kmod_loop_msg++;
-		}
-		return -ENOMEM;
+		pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...",
+				    atomic_read(&kmod_concurrent_max),
+				    MAX_KMOD_CONCURRENT, module_name);
+		wait_event_interruptible(kmod_wq,
+					 atomic_dec_if_positive(&kmod_concurrent_max) >= 0);
 	}
 
 	trace_module_request(module_name, wait, _RET_IP_);
@@ -179,6 +176,7 @@ int __request_module(bool wait, const char *fmt, ...)
 	ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
 
 	atomic_inc(&kmod_concurrent_max);
+	wake_up(&kmod_wq);
 
 	return ret;
 }
diff --git a/tools/testing/selftests/kmod/kmod.sh b/tools/testing/selftests/kmod/kmod.sh
index 10196a62ed09..8cecae9a8bca 100755
--- a/tools/testing/selftests/kmod/kmod.sh
+++ b/tools/testing/selftests/kmod/kmod.sh
@@ -59,28 +59,8 @@ ALL_TESTS="$ALL_TESTS 0004:1:1"
 ALL_TESTS="$ALL_TESTS 0005:10:1"
 ALL_TESTS="$ALL_TESTS 0006:10:1"
 ALL_TESTS="$ALL_TESTS 0007:5:1"
-
-# Disabled tests:
-#
-# 0008 x 150 -  multithreaded - push kmod_concurrent over max_modprobes for request_module()"
-# Current best-effort failure interpretation:
-# Enough module requests get loaded in place fast enough to reach over the
-# max_modprobes limit and trigger a failure -- before we're even able to
-# start processing pending requests.
-ALL_TESTS="$ALL_TESTS 0008:150:0"
-
-# 0009 x 150 - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()"
-# Current best-effort failure interpretation:
-#
-# get_fs_type() requests modules using aliases as such the optimization in
-# place today to look for already loaded modules will not take effect and
-# we end up requesting a new module to load, this bumps the kmod_concurrent,
-# and in certain circumstances can lead to pushing the kmod_concurrent over
-# the max_modprobe limit.
-#
-# This test fails much easier than test 0008 since the alias optimizations
-# are not in place.
-ALL_TESTS="$ALL_TESTS 0009:150:0"
+ALL_TESTS="$ALL_TESTS 0008:150:1"
+ALL_TESTS="$ALL_TESTS 0009:150:1"
 
 test_modprobe()
 {
-- 
2.11.0

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web