13 Aug, 2020

1 commit

  • Reset the member "test_fs" of the test configuration after a call of the
    function "kfree_const" to a null pointer so that a double memory release
    will not be performed.

    Fixes: d9c6a72d6fa2 ("kmod: add test driver to stress test the module loader")
    Signed-off-by: Tiezhu Yang
    Signed-off-by: Luis Chamberlain
    Signed-off-by: Andrew Morton
    Acked-by: Luis Chamberlain
    Cc: Alexei Starovoitov
    Cc: Al Viro
    Cc: Christian Brauner
    Cc: Chuck Lever
    Cc: David Howells
    Cc: David S. Miller
    Cc: Greg Kroah-Hartman
    Cc: Jakub Kicinski
    Cc: James Morris
    Cc: Jarkko Sakkinen
    Cc: J. Bruce Fields
    Cc: Jens Axboe
    Cc: Josh Triplett
    Cc: Kees Cook
    Cc: Lars Ellenberg
    Cc: Nikolay Aleksandrov
    Cc: Philipp Reisner
    Cc: Roopa Prabhu
    Cc: "Serge E. Hallyn"
    Cc: Sergei Trofimovich
    Cc: Sergey Kvachonok
    Cc: Shuah Khan
    Cc: Tony Vroon
    Cc: Christoph Hellwig
    Link: http://lkml.kernel.org/r/20200610154923.27510-4-mcgrof@kernel.org
    Signed-off-by: Linus Torvalds

    Tiezhu Yang
     

08 Apr, 2020

1 commit

  • The "info" pointer has already been dereferenced so checking here is too
    late. Fortunately, we never pass NULL pointers to the
    test_kmod_put_module() function so the test can simply be removed.

    Signed-off-by: Dan Carpenter
    Signed-off-by: Andrew Morton
    Acked-by: Luis Chamberlain
    Link: http://lkml.kernel.org/r/20200228092452.vwkhthsn77nrxdy6@kili.mountain
    Signed-off-by: Linus Torvalds

    Dan Carpenter
     

02 Feb, 2019

1 commit

  • There is a copy and paste bug so we set "config->test_driver" to NULL
    twice instead of setting "config->test_fs". Smatch complains that it
    leads to a double free:

    lib/test_kmod.c:840 __kmod_config_init() warn: 'config->test_fs' double freed

    Link: http://lkml.kernel.org/r/20190121140011.GA14283@kadam
    Fixes: d9c6a72d6fa2 ("kmod: add test driver to stress test the module loader")
    Signed-off-by: Dan Carpenter
    Acked-by: Luis Chamberlain
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Dan Carpenter
     

01 Dec, 2018

1 commit

  • We free the misc device string twice on rmmod; fix this. Without this
    we cannot remove the module without crashing.

    Link: http://lkml.kernel.org/r/20181124050500.5257-1-mcgrof@kernel.org
    Signed-off-by: Luis Chamberlain
    Reported-by: Randy Dunlap
    Reviewed-by: Andrew Morton
    Cc: [4.12+]
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Luis Chamberlain
     

13 Jun, 2018

1 commit

  • The vzalloc() function has no 2-factor argument form, so multiplication
    factors need to be wrapped in array_size(). This patch replaces cases of:

    vzalloc(a * b)

    with:
    vzalloc(array_size(a, b))

    as well as handling cases of:

    vzalloc(a * b * c)

    with:

    vzalloc(array3_size(a, b, c))

    This does, however, attempt to ignore constant size factors like:

    vzalloc(4 * 1024)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    vzalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    vzalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    vzalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    vzalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    vzalloc(
    - sizeof(TYPE) * (COUNT_ID)
    + array_size(COUNT_ID, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE) * COUNT_ID
    + array_size(COUNT_ID, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE) * (COUNT_CONST)
    + array_size(COUNT_CONST, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE) * COUNT_CONST
    + array_size(COUNT_CONST, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * (COUNT_ID)
    + array_size(COUNT_ID, sizeof(THING))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * COUNT_ID
    + array_size(COUNT_ID, sizeof(THING))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * (COUNT_CONST)
    + array_size(COUNT_CONST, sizeof(THING))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * COUNT_CONST
    + array_size(COUNT_CONST, sizeof(THING))
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    vzalloc(
    - SIZE * COUNT
    + array_size(COUNT, SIZE)
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    vzalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    vzalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    vzalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    vzalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    vzalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    vzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    vzalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    vzalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    vzalloc(C1 * C2 * C3, ...)
    |
    vzalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants.
    @@
    expression E1, E2;
    constant C1, C2;
    @@

    (
    vzalloc(C1 * C2, ...)
    |
    vzalloc(
    - E1 * E2
    + array_size(E1, E2)
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

10 Mar, 2018

1 commit

  • As reported by Dan the parentheses is in the wrong place, and since
    unlikely() call returns either 0 or 1 it's never less than zero. The
    second issue is that signed integer overflows like "INT_MAX + 1" are
    undefined behavior.

    Since num_test_devs represents the number of devices, we want to stop
    prior to hitting the max, and not rely on the wrap arround at all. So
    just cap at num_test_devs + 1, prior to assigning a new device.

    Link: http://lkml.kernel.org/r/20180224030046.24238-1-mcgrof@kernel.org
    Fixes: d9c6a72d6fa2 ("kmod: add test driver to stress test the module loader")
    Reported-by: Dan Carpenter
    Signed-off-by: Luis R. Rodriguez
    Acked-by: Kees Cook
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Luis R. Rodriguez
     

09 Jan, 2018

1 commit

  • Convert DEVICE_ATTR uses to DEVICE_ATTR_RW where possible.

    Done with perl script:

    $ git grep -w --name-only DEVICE_ATTR | \
    xargs perl -i -e 'local $/; while (<>) { s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(\s*S_IRUGO\s*\|\s*S_IWUSR|\s*S_IWUSR\s*\|\s*S_IRUGO\s*|\s*0644\s*)\)?\s*,\s*\1_show\s*,\s*\1_store\s*\)/DEVICE_ATTR_RW(\1)/g; print;}'

    Signed-off-by: Joe Perches
    Acked-by: Felipe Balbi
    Acked-by: Andy Shevchenko
    Acked-by: Bartlomiej Zolnierkiewicz
    Acked-by: Zhang Rui
    Acked-by: Jarkko Nikula
    Acked-by: Jani Nikula
    Signed-off-by: Greg Kroah-Hartman

    Joe Perches
     

18 Nov, 2017

1 commit


09 Sep, 2017

2 commits

  • Most checks will check for min and then max, except the int check. Flip
    the checks to be consistent with the other code.

    [mcgrof@kernel.org: massaged commit log]
    Link: http://lkml.kernel.org/r/20170802211707.28020-3-mcgrof@kernel.org
    Signed-off-by: Dan Carpenter
    Signed-off-by: Luis R. Rodriguez
    Cc: Dmitry Torokhov
    Cc: Kees Cook
    Cc: Jessica Yu
    Cc: Rusty Russell
    Cc: Michal Marek
    Cc: Petr Mladek
    Cc: Miroslav Benes
    Cc: Josh Poimboeuf
    Cc: Eric W. Biederman
    Cc: Shuah Khan
    Cc: Colin Ian King
    Cc: David Binderman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Dan Carpenter
     
  • The UINT_MAX comparison is not needed because "max" is already an unsigned
    int, and we expect developer C code max value input to have a sensible 0 -
    UINT_MAX range. Note that if it so happens to be UINT_MAX + 1 it would
    lead to an issue, but we expect the developer to know this.

    [mcgrof@kernel.org: massaged commit log]
    Link: http://lkml.kernel.org/r/20170802211707.28020-2-mcgrof@kernel.org
    Signed-off-by: Dan Carpenter
    Signed-off-by: Luis R. Rodriguez
    Cc: Dmitry Torokhov
    Cc: Kees Cook
    Cc: Jessica Yu
    Cc: Rusty Russell
    Cc: Michal Marek
    Cc: Petr Mladek
    Cc: Miroslav Benes
    Cc: Josh Poimboeuf
    Cc: Eric W. Biederman
    Cc: Shuah Khan
    Cc: Colin Ian King
    Cc: David Binderman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Dan Carpenter
     

11 Aug, 2017

4 commits

  • The break was in the wrong place so file system tests don't work as
    intended, leaking memory at each test switch.

    [mcgrof@kernel.org: massaged commit subject, noted memory leak issue without the fix]
    Link: http://lkml.kernel.org/r/20170802211450.27928-6-mcgrof@kernel.org
    Fixes: 39258f448d71 ("kmod: add test driver to stress test the module loader")
    Signed-off-by: Dan Carpenter
    Signed-off-by: Luis R. Rodriguez
    Reported-by: David Binderman
    Cc: Colin Ian King
    Cc: Dmitry Torokhov
    Cc: Eric W. Biederman
    Cc: Jessica Yu
    Cc: Josh Poimboeuf
    Cc: Kees Cook
    Cc: Michal Marek
    Cc: Miroslav Benes
    Cc: Petr Mladek
    Cc: Rusty Russell
    Cc: Shuah Khan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Dan Carpenter
     
  • We accidentally just drop the lock twice instead of taking it and then
    releasing it. This isn't a big issue unless you are adding more than
    one device to test on, and the kmod.sh doesn't do that yet, however this
    obviously is the correct thing to do.

    [mcgrof@kernel.org: massaged subject, explain what happens]
    Link: http://lkml.kernel.org/r/20170802211450.27928-5-mcgrof@kernel.org
    Fixes: 39258f448d71 ("kmod: add test driver to stress test the module loader")
    Signed-off-by: Dan Carpenter
    Signed-off-by: Luis R. Rodriguez
    Cc: Colin Ian King
    Cc: David Binderman
    Cc: Dmitry Torokhov
    Cc: Eric W. Biederman
    Cc: Jessica Yu
    Cc: Josh Poimboeuf
    Cc: Kees Cook
    Cc: Michal Marek
    Cc: Miroslav Benes
    Cc: Petr Mladek
    Cc: Rusty Russell
    Cc: Shuah Khan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Dan Carpenter
     
  • Parsing with kstrtol() enables values to be negative, and we failed to
    check for negative values when parsing with test_dev_config_update_uint_sync()
    or test_dev_config_update_uint_range().

    test_dev_config_update_uint_range() has a minimum check though so an
    issue is not present there. test_dev_config_update_uint_sync() is only
    used for the number of threads to use (config_num_threads_store()), and
    indeed this would fail with an attempt for a large allocation.

    Although the issue is only present in practice with the first fix both
    by using kstrtoul() instead of kstrtol().

    Link: http://lkml.kernel.org/r/20170802211450.27928-4-mcgrof@kernel.org
    Fixes: 39258f448d71 ("kmod: add test driver to stress test the module loader")
    Signed-off-by: Luis R. Rodriguez
    Reported-by: Dan Carpenter
    Cc: Colin Ian King
    Cc: David Binderman
    Cc: Dmitry Torokhov
    Cc: Eric W. Biederman
    Cc: Jessica Yu
    Cc: Josh Poimboeuf
    Cc: Kees Cook
    Cc: Michal Marek
    Cc: Miroslav Benes
    Cc: Petr Mladek
    Cc: Rusty Russell
    Cc: Shuah Khan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Luis R. Rodriguez
     
  • Trivial fix to spelling mistake in snprintf text

    [mcgrof@kernel.org: massaged commit message]
    Link: http://lkml.kernel.org/r/20170802211450.27928-3-mcgrof@kernel.org
    Fixes: 39258f448d71 ("kmod: add test driver to stress test the module loader")
    Signed-off-by: Colin Ian King
    Signed-off-by: Luis R. Rodriguez
    Cc: Dmitry Torokhov
    Cc: Kees Cook
    Cc: Jessica Yu
    Cc: Rusty Russell
    Cc: Michal Marek
    Cc: Petr Mladek
    Cc: Miroslav Benes
    Cc: Josh Poimboeuf
    Cc: Eric W. Biederman
    Cc: Shuah Khan
    Cc: Dan Carpenter
    Cc: David Binderman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Colin Ian King
     

15 Jul, 2017

1 commit

  • This adds a new stress test driver for kmod: the kernel module loader.
    The new stress test driver, test_kmod, is only enabled as a module right
    now. It should be possible to load this as built-in and load tests
    early (refer to the force_init_test module parameter), however since a
    lot of test can get a system out of memory fast we leave this disabled
    for now.

    Using a system with 1024 MiB of RAM can *easily* get your kernel OOM
    fast with this test driver.

    The test_kmod driver exposes API knobs for us to fine tune simple
    request_module() and get_fs_type() calls. Since these API calls only
    allow each one parameter a test driver for these is rather simple.
    Other factors that can help out test driver though are the number of
    calls we issue and knowing current limitations of each. This exposes
    configuration as much as possible through userspace to be able to build
    tests directly from userspace.

    Since it allows multiple misc devices its will eventually (once we add a
    knob to let us create new devices at will) also be possible to perform
    more tests in parallel, provided you have enough memory.

    We only enable tests we know work as of right now.

    Demo screenshots:

    # tools/testing/selftests/kmod/kmod.sh
    kmod_test_0001_driver: OK! - loading kmod test
    kmod_test_0001_driver: OK! - Return value: 256 (MODULE_NOT_FOUND), expected MODULE_NOT_FOUND
    kmod_test_0001_fs: OK! - loading kmod test
    kmod_test_0001_fs: OK! - Return value: -22 (-EINVAL), expected -EINVAL
    kmod_test_0002_driver: OK! - loading kmod test
    kmod_test_0002_driver: OK! - Return value: 256 (MODULE_NOT_FOUND), expected MODULE_NOT_FOUND
    kmod_test_0002_fs: OK! - loading kmod test
    kmod_test_0002_fs: OK! - Return value: -22 (-EINVAL), expected -EINVAL
    kmod_test_0003: OK! - loading kmod test
    kmod_test_0003: OK! - Return value: 0 (SUCCESS), expected SUCCESS
    kmod_test_0004: OK! - loading kmod test
    kmod_test_0004: OK! - Return value: 0 (SUCCESS), expected SUCCESS
    kmod_test_0005: OK! - loading kmod test
    kmod_test_0005: OK! - Return value: 0 (SUCCESS), expected SUCCESS
    kmod_test_0006: OK! - loading kmod test
    kmod_test_0006: OK! - Return value: 0 (SUCCESS), expected SUCCESS
    kmod_test_0005: OK! - loading kmod test
    kmod_test_0005: OK! - Return value: 0 (SUCCESS), expected SUCCESS
    kmod_test_0006: OK! - loading kmod test
    kmod_test_0006: OK! - Return value: 0 (SUCCESS), expected SUCCESS
    XXX: add test restult for 0007
    Test completed

    You can also request for specific tests:

    # tools/testing/selftests/kmod/kmod.sh -t 0001
    kmod_test_0001_driver: OK! - loading kmod test
    kmod_test_0001_driver: OK! - Return value: 256 (MODULE_NOT_FOUND), expected MODULE_NOT_FOUND
    kmod_test_0001_fs: OK! - loading kmod test
    kmod_test_0001_fs: OK! - Return value: -22 (-EINVAL), expected -EINVAL
    Test completed

    Lastly, the current available number of tests:

    # tools/testing/selftests/kmod/kmod.sh --help
    Usage: tools/testing/selftests/kmod/kmod.sh [ -t ]
    Valid tests: 0001-0009

    0001 - Simple test - 1 thread for empty string
    0002 - Simple test - 1 thread for modules/filesystems that do not exist
    0003 - Simple test - 1 thread for get_fs_type() only
    0004 - Simple test - 2 threads for get_fs_type() only
    0005 - multithreaded tests with default setup - request_module() only
    0006 - multithreaded tests with default setup - get_fs_type() only
    0007 - multithreaded tests with default setup test request_module() and get_fs_type()
    0008 - multithreaded - push kmod_concurrent over max_modprobes for request_module()
    0009 - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()

    The following test cases currently fail, as such they are not currently
    enabled by default:

    # tools/testing/selftests/kmod/kmod.sh -t 0008
    # tools/testing/selftests/kmod/kmod.sh -t 0009

    To be sure to run them as intended please unload both of the modules:

    o test_module
    o xfs

    And ensure they are not loaded on your system prior to testing them. If
    you use these paritions for your rootfs you can change the default test
    driver used for get_fs_type() by exporting it into your environment. For
    example of other test defaults you can override refer to kmod.sh
    allow_user_defaults().

    Behind the scenes this is how we fine tune at a test case prior to
    hitting a trigger to run it:

    cat /sys/devices/virtual/misc/test_kmod0/config
    echo -n "2" > /sys/devices/virtual/misc/test_kmod0/config_test_case
    echo -n "ext4" > /sys/devices/virtual/misc/test_kmod0/config_test_fs
    echo -n "80" > /sys/devices/virtual/misc/test_kmod0/config_num_threads
    cat /sys/devices/virtual/misc/test_kmod0/config
    echo -n "1" > /sys/devices/virtual/misc/test_kmod0/config_num_threads

    Finally to trigger:

    echo -n "1" > /sys/devices/virtual/misc/test_kmod0/trigger_config

    The kmod.sh script uses the above constructs to build different test cases.

    A bit of interpretation of the current failures follows, first two
    premises:

    a) When request_module() is used userspace figures out an optimized
    version of module order for us. Once it finds the modules it needs, as
    per depmod symbol dep map, it will finit_module() the respective
    modules which are needed for the original request_module() request.

    b) We have an optimization in place whereby if a kernel uses
    request_module() on a module already loaded we never bother userspace
    as the module already is loaded. This is all handled by kernel/kmod.c.

    A few things to consider to help identify root causes of issues:

    0) kmod 19 has a broken heuristic for modules being assumed to be
    built-in to your kernel and will return 0 even though request_module()
    failed. Upgrade to a newer version of kmod.

    1) A get_fs_type() call for "xfs" will request_module() for "fs-xfs",
    not for "xfs". The optimization in kernel described in b) fails to
    catch if we have a lot of consecutive get_fs_type() calls. The reason
    is the optimization in place does not look for aliases. This means two
    consecutive get_fs_type() calls will bump kmod_concurrent, whereas
    request_module() will not.

    This one explanation why test case 0009 fails at least once for
    get_fs_type().

    2) If a module fails to load --- for whatever reason (kmod_concurrent
    limit reached, file not yet present due to rootfs switch, out of
    memory) we have a period of time during which module request for the
    same name either with request_module() or get_fs_type() will *also*
    fail to load even if the file for the module is ready.

    This explains why *multiple* NULLs are possible on test 0009.

    3) finit_module() consumes quite a bit of memory.

    4) Filesystems typically also have more dependent modules than other
    modules, its important to note though that even though a get_fs_type()
    call does not incur additional kmod_concurrent bumps, since userspace
    loads dependencies it finds it needs via finit_module_fd(), it *will*
    take much more memory to load a module with a lot of dependencies.

    Because of 3) and 4) we will easily run into out of memory failures with
    certain tests. For instance test 0006 fails on qemu with 1024 MiB of RAM.
    It panics a box after reaping all userspace processes and still not
    having enough memory to reap.

    [arnd@arndb.de: add dependencies for test module]
    Link: http://lkml.kernel.org/r/20170630154834.3689272-1-arnd@arndb.de
    Link: http://lkml.kernel.org/r/20170628223155.26472-3-mcgrof@kernel.org
    Signed-off-by: Luis R. Rodriguez
    Cc: Jessica Yu
    Cc: Shuah Khan
    Cc: Rusty Russell
    Cc: Michal Marek
    Cc: Petr Mladek
    Cc: Greg Kroah-Hartman
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Luis R. Rodriguez