Skip to content
Snippets Groups Projects
  1. Jan 26, 2024
    • Marco Elver's avatar
      stackdepot: make fast paths lock-less again · 4434a56e
      Marco Elver authored
      With the introduction of the pool_rwlock (reader-writer lock), several
      fast paths end up taking the pool_rwlock as readers.  Furthermore,
      stack_depot_put() unconditionally takes the pool_rwlock as a writer.
      
      Despite allowing readers to make forward-progress concurrently,
      reader-writer locks have inherent cache contention issues, which does not
      scale well on systems with large CPU counts.
      
      Rework the synchronization story of stack depot to again avoid taking any
      locks in the fast paths.  This is done by relying on RCU-protected list
      traversal, and the NMI-safe subset of RCU to delay reuse of freed stack
      records.  See code comments for more details.
      
      Along with the performance issues, this also fixes incorrect nesting of
      rwlock within a raw_spinlock, given that stack depot should still be
      usable from anywhere:
      
       | [ BUG: Invalid wait context ]
       | -----------------------------
       | swapper/0/1 is trying to lock:
       | ffffffff89869be8 (pool_rwlock){..--}-{3:3}, at: stack_depot_save_flags
       | other info that might help us debug this:
       | context-{5:5}
       | 2 locks held by swapper/0/1:
       |  #0: ffffffff89632440 (rcu_read_lock){....}-{1:3}, at: __queue_work
       |  #1: ffff888100092018 (&pool->lock){-.-.}-{2:2}, at: __queue_work  <-- raw_spin_lock
      
      Stack depot usage stats are similar to the previous version after a KASAN
      kernel boot:
      
       $ cat /sys/kernel/debug/stackdepot/stats
       pools: 838
       allocations: 29865
       frees: 6604
       in_use: 23261
       freelist_size: 1879
      
      The number of pools is the same as previously.  The freelist size is
      minimally larger, but this may also be due to variance across system
      boots.  This shows that even though we do not eagerly wait for the next
      RCU grace period (such as with synchronize_rcu() or call_rcu()) after
      freeing a stack record - requiring depot_pop_free() to "poll" if an entry
      may be used - new allocations are very likely to happen in later RCU grace
      periods.
      
      Link: https://lkml.kernel.org/r/20240118110216.2539519-2-elver@google.com
      
      
      Fixes: 108be8de ("lib/stackdepot: allow users to evict stack traces")
      Reported-by: default avatarAndi Kleen <ak@linux.intel.com>
      Signed-off-by: default avatarMarco Elver <elver@google.com>
      Reviewed-by: default avatarAndrey Konovalov <andreyknvl@gmail.com>
      Cc: Alexander Potapenko <glider@google.com>
      Cc: Andrey Konovalov <andreyknvl@gmail.com>
      Cc: Dmitry Vyukov <dvyukov@google.com>
      Cc: Vlastimil Babka <vbabka@suse.cz>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      4434a56e
    • Marco Elver's avatar
      stackdepot: add stats counters exported via debugfs · c2a29254
      Marco Elver authored
      Add a few basic stats counters for stack depot that can be used to derive
      if stack depot is working as intended.  This is a snapshot of the new
      stats after booting a system with a KASAN-enabled kernel:
      
       $ cat /sys/kernel/debug/stackdepot/stats
       pools: 838
       allocations: 29861
       frees: 6561
       in_use: 23300
       freelist_size: 1840
      
      Generally, "pools" should be well below the max; once the system is
      booted, "in_use" should remain relatively steady.
      
      Link: https://lkml.kernel.org/r/20240118110216.2539519-1-elver@google.com
      
      
      Signed-off-by: default avatarMarco Elver <elver@google.com>
      Reviewed-by: default avatarAndrey Konovalov <andreyknvl@gmail.com>
      Cc: Andi Kleen <ak@linux.intel.com>
      Cc: Dmitry Vyukov <dvyukov@google.com>
      Cc: Vlastimil Babka <vbabka@suse.cz>
      Cc: Alexander Potapenko <glider@google.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      c2a29254
  2. Jan 22, 2024
    • Marco Pagani's avatar
      kunit: run test suites only after module initialization completes · a1af6a2b
      Marco Pagani authored
      
      Commit 2810c1e9 ("kunit: Fix wild-memory-access bug in
      kunit_free_suite_set()") fixed a wild-memory-access bug that could have
      happened during the loading phase of test suites built and executed as
      loadable modules. However, it also introduced a problematic side effect
      that causes test suites modules to crash when they attempt to register
      fake devices.
      
      When a module is loaded, it traverses the MODULE_STATE_UNFORMED and
      MODULE_STATE_COMING states before reaching the normal operating state
      MODULE_STATE_LIVE. Finally, when the module is removed, it moves to
      MODULE_STATE_GOING before being released. However, if the loading
      function load_module() fails between complete_formation() and
      do_init_module(), the module goes directly from MODULE_STATE_COMING to
      MODULE_STATE_GOING without passing through MODULE_STATE_LIVE.
      
      This behavior was causing kunit_module_exit() to be called without
      having first executed kunit_module_init(). Since kunit_module_exit() is
      responsible for freeing the memory allocated by kunit_module_init()
      through kunit_filter_suites(), this behavior was resulting in a
      wild-memory-access bug.
      
      Commit 2810c1e9 ("kunit: Fix wild-memory-access bug in
      kunit_free_suite_set()") fixed this issue by running the tests when the
      module is still in MODULE_STATE_COMING. However, modules in that state
      are not fully initialized, lacking sysfs kobjects. Therefore, if a test
      module attempts to register a fake device, it will inevitably crash.
      
      This patch proposes a different approach to fix the original
      wild-memory-access bug while restoring the normal module execution flow
      by making kunit_module_exit() able to detect if kunit_module_init() has
      previously initialized the tests suite set. In this way, test modules
      can once again register fake devices without crashing.
      
      This behavior is achieved by checking whether mod->kunit_suites is a
      virtual or direct mapping address. If it is a virtual address, then
      kunit_module_init() has allocated the suite_set in kunit_filter_suites()
      using kmalloc_array(). On the contrary, if mod->kunit_suites is still
      pointing to the original address that was set when looking up the
      .kunit_test_suites section of the module, then the loading phase has
      failed and there's no memory to be freed.
      
      v4:
      - rebased on 6.8
      - noted that kunit_filter_suites() must return a virtual address
      v3:
      - add a comment to clarify why the start address is checked
      v2:
      - add include <linux/mm.h>
      
      Fixes: 2810c1e9 ("kunit: Fix wild-memory-access bug in kunit_free_suite_set()")
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Tested-by: default avatarRae Moar <rmoar@google.com>
      Tested-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
      Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
      Signed-off-by: default avatarMarco Pagani <marpagan@redhat.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      a1af6a2b
    • Dan Carpenter's avatar
      kunit: device: Fix a NULL vs IS_ERR() check in init() · 083974eb
      Dan Carpenter authored
      
      The root_device_register() function does not return NULL, it returns
      error pointers.  Fix the check to match.
      
      Fixes: d03c720e ("kunit: Add APIs for managing devices")
      Signed-off-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
      Reviewed-by: default avatarRae Moar <rmoar@google.com>
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      083974eb
    • Dan Carpenter's avatar
      kunit: Fix a NULL vs IS_ERR() bug · ed1a72fb
      Dan Carpenter authored
      
      The kunit_device_register() function doesn't return NULL, it returns
      error pointers.  Change the KUNIT_ASSERT_NOT_NULL() to check for
      ERR_OR_NULL().
      
      Fixes: d03c720e ("kunit: Add APIs for managing devices")
      Signed-off-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
      Reviewed-by: default avatarRae Moar <rmoar@google.com>
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      ed1a72fb
  3. Jan 19, 2024
  4. Jan 18, 2024
  5. Jan 15, 2024
  6. Jan 12, 2024
  7. Jan 08, 2024
  8. Jan 03, 2024
  9. Dec 29, 2023
  10. Dec 28, 2023
  11. Dec 27, 2023
  12. Dec 22, 2023
  13. Dec 21, 2023
  14. Dec 20, 2023
  15. Dec 18, 2023
    • mwajdecz's avatar
      kunit: Reset test->priv after each param iteration · 342fb978
      mwajdecz authored
      
      If we run parameterized test that uses test->priv to prepare some
      custom data, then value of test->priv will leak to the next param
      iteration and may be unexpected.  This could be easily seen if
      we promote example_priv_test to parameterized test as then only
      first test iteration will be successful:
      
      $ ./tools/testing/kunit/kunit.py run \
      	--kunitconfig ./lib/kunit/.kunitconfig *.example_priv*
      
      [ ] Starting KUnit Kernel (1/1)...
      [ ] ============================================================
      [ ] =================== example (1 subtest) ====================
      [ ] ==================== example_priv_test  ====================
      [ ] [PASSED] example value 3
      [ ] # example_priv_test: initializing
      [ ] # example_priv_test: ASSERTION FAILED at lib/kunit/kunit-example-test.c:230
      [ ] Expected test->priv == ((void *)0), but
      [ ]     test->priv == 0000000060dfe290
      [ ]     ((void *)0) == 0000000000000000
      [ ] # example_priv_test: cleaning up
      [ ] [FAILED] example value 2
      [ ] # example_priv_test: initializing
      [ ] # example_priv_test: ASSERTION FAILED at lib/kunit/kunit-example-test.c:230
      [ ] Expected test->priv == ((void *)0), but
      [ ]     test->priv == 0000000060dfe290
      [ ]     ((void *)0) == 0000000000000000
      [ ] # example_priv_test: cleaning up
      [ ] [FAILED] example value 1
      [ ] # example_priv_test: initializing
      [ ] # example_priv_test: ASSERTION FAILED at lib/kunit/kunit-example-test.c:230
      [ ] Expected test->priv == ((void *)0), but
      [ ]     test->priv == 0000000060dfe290
      [ ]     ((void *)0) == 0000000000000000
      [ ] # example_priv_test: cleaning up
      [ ] [FAILED] example value 0
      [ ] # example_priv_test: initializing
      [ ] # example_priv_test: cleaning up
      [ ] # example_priv_test: pass:1 fail:3 skip:0 total:4
      [ ] ================ [FAILED] example_priv_test ================
      [ ]     # example: initializing suite
      [ ]     # module: kunit_example_test
      [ ]     # example: exiting suite
      [ ] # Totals: pass:1 fail:3 skip:0 total:4
      [ ] ===================== [FAILED] example =====================
      
      Fix that by resetting test->priv after each param iteration, in
      similar way what we did for the test->status.
      
      Signed-off-by: default avatarMichal Wajdeczko <michal.wajdeczko@intel.com>
      Cc: David Gow <davidgow@google.com>
      Cc: Rae Moar <rmoar@google.com>
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      342fb978
    • mwajdecz's avatar
      kunit: Add example for using test->priv · 2b61582a
      mwajdecz authored
      
      In a test->priv field the user can store arbitrary data.
      Add example how to use this feature in the test code.
      
      Signed-off-by: default avatarMichal Wajdeczko <michal.wajdeczko@intel.com>
      Cc: David Gow <davidgow@google.com>
      Cc: Rae Moar <rmoar@google.com>
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      2b61582a
    • davidgow@google.com's avatar
      overflow: Replace fake root_device with kunit_device · 83701838
      davidgow@google.com authored
      
      Using struct root_device to create fake devices for tests is something
      of a hack. The new struct kunit_device is meant for this purpose, so use
      it instead.
      
      Reviewed-by: default avatarMatti Vaittinen <mazziesaccount@gmail.com>
      Acked-by: default avatarKees Cook <keescook@chromium.org>
      Signed-off-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      83701838
    • davidgow@google.com's avatar
      fortify: test: Use kunit_device · 46ee8f68
      davidgow@google.com authored
      
      Using struct root_device to create fake devices for tests is something
      of a hack. The new struct kunit_device is meant for this purpose, so use
      it instead.
      
      Reviewed-by: default avatarMatti Vaittinen <mazziesaccount@gmail.com>
      Acked-by: default avatarKees Cook <keescook@chromium.org>
      Signed-off-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      46ee8f68
    • davidgow@google.com's avatar
      kunit: Add APIs for managing devices · d03c720e
      davidgow@google.com authored
      
      Tests for drivers often require a struct device to pass to other
      functions. While it's possible to create these with
      root_device_register(), or to use something like a platform device, this
      is both a misuse of those APIs, and can be difficult to clean up after,
      for example, a failed assertion.
      
      Add some KUnit-specific functions for registering and unregistering a
      struct device:
      - kunit_device_register()
      - kunit_device_register_with_driver()
      - kunit_device_unregister()
      
      These helpers allocate a on a 'kunit' bus which will either probe the
      driver passed in (kunit_device_register_with_driver), or will create a
      stub driver (kunit_device_register) which is cleaned up on test shutdown.
      
      Devices are automatically unregistered on test shutdown, but can be
      manually unregistered earlier with kunit_device_unregister() in order
      to, for example, test device release code.
      
      Reviewed-by: default avatarMatti Vaittinen <mazziesaccount@gmail.com>
      Reviewed-by: Maxime Ripard's avatarMaxime Ripard <mripard@kernel.org>
      Signed-off-by: default avatarDavid Gow <davidgow@google.com>
      Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      d03c720e
    • Rae Moar's avatar
      kunit: add ability to run tests after boot using debugfs · c72a8709
      Rae Moar authored
      
      Add functionality to run built-in tests after boot by writing to a
      debugfs file.
      
      Add a new debugfs file labeled "run" for each test suite to use for
      this purpose.
      
      As an example, write to the file using the following:
      
      echo "any string" > /sys/kernel/debugfs/kunit/<testsuite>/run
      
      This will trigger the test suite to run and will print results to the
      kernel log.
      
      To guard against running tests concurrently with this feature, add a
      mutex lock around running kunit. This supports the current practice of
      not allowing tests to be run concurrently on the same kernel.
      
      This new functionality could be used to design a parameter
      injection feature in the future.
      
      Fixed up merge conflict duing rebase to Linux 6.7-rc6
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarRae Moar <rmoar@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      c72a8709
    • Rae Moar's avatar
      kunit: add is_init test attribute · 6c4ea2f4
      Rae Moar authored
      
      Add is_init test attribute of type bool. Add to_string, get, and filter
      methods to lib/kunit/attributes.c.
      
      Mark each of the tests in the init section with the is_init=true attribute.
      
      Add is_init to the attributes documentation.
      
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarRae Moar <rmoar@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      6c4ea2f4
    • Rae Moar's avatar
      kunit: add example suite to test init suites · 2cf45281
      Rae Moar authored
      
      Add example_init_test_suite to allow for testing the feature of running
      test suites marked as init to indicate they use init data and/or
      functions.
      
      This suite should always pass and uses a simple init function.
      
      This suite can also be used to test the is_init attribute introduced in
      the next patch.
      
      Signed-off-by: default avatarRae Moar <rmoar@google.com>
      Reviewed-by: default avatarDavid Gow <davidgow@google.com>
      Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
      2cf45281
Loading