On Fri, Sep 25, 2020 at 05:47:14PM -0600, Shuah Khan wrote:
This patch series is a result of discussion at the refcount_t BOF the Linux Plumbers Conference. In this discussion, we identified a need for looking closely and investigating atomic_t usages in the kernel when it is used strictly as a counter without it controlling object lifetimes and state changes.
There are a number of atomic_t usages in the kernel where atomic_t api is used strictly for counting and not for managing object lifetime. In some cases, atomic_t might not even be needed. The purpose of these counters is twofold: 1. clearly differentiate atomic_t counters from atomic_t usages that guard object lifetimes, hence prone to overflow and underflow errors. It allows tools that scan for underflow and overflow on atomic_t usages to detect overflow and underflows to scan just the cases that are prone to errors. 2. provides non-atomic counters for cases where atomic isn't necessary.
Nice series :)
It appears there is no user of counter_simple in this series other than the selftest. Would you be planning to add any conversions in the series itself, for illustration of use? Sorry if I missed a usage.
Also how do we guard against atomicity of counter_simple RMW operations? Is the implication that it should be guarded using other synchronization to prevent lost-update problem?
Some more comments:
1. atomic RMW operations that have a return value are fully ordered. Would you be adding support to counter_simple for such ordering as well, for consistency?
2. I felt counter_atomic and counter_atomic64 would be nice equivalents to the atomic and atomic64 naming currently used (i.e. dropping the '32'). However that is just my opinion and I am ok with either naming.
thanks!
- Joel
Simple atomic and non-atomic counters api provides interfaces for simple atomic and non-atomic counters that just count, and don't guard resource lifetimes. Counters will wrap around to 0 when it overflows and should not be used to guard resource lifetimes, device usage and open counts that control state changes, and pm states. Using counter_atomic to guard lifetimes could lead to use-after free when it overflows and undefined behavior when used to manage state changes and device usage/open states.
This patch series introduces Simple atomic and non-atomic counters. Counter atomic ops leverage atomic_t and provide a sub-set of atomic_t ops.
In addition this patch series converts a few drivers to use the new api. The following criteria is used for select variables for conversion:
- Variable doesn't guard object lifetimes, manage state changes e.g: device usage counts, device open counts, and pm states.
- Variable is used for stats and counters.
- The conversion doesn't change the overflow behavior.
Changes since RFC: -- Thanks for reviews and reviewed-by, and Acked-by tags. Updated the patches with the tags. -- Addressed Kees's comments:
- Non-atomic counters renamed to counter_simple32 and counter_simple64 to clearly indicate size.
- Added warning for counter_simple* usage and it should be used only when there is no need for atomicity.
- Renamed counter_atomic to counter_atomic32 to clearly indicate size.
- Renamed counter_atomic_long to counter_atomic64 and it now uses atomic64_t ops and indicates size.
- Test updated for the API renames.
- Added helper functions for test results printing
- Verified that the test module compiles in kunit env. and test module can be loaded to run the test.
- Updated Documentation to reflect the intent to make the API restricted so it can never be used to guard object lifetimes and state management. I left _return ops for now, inc_return is necessary for now as per the discussion we had on this topic.
-- Updated driver patches with API name changes. -- We discussed if binder counters can be non-atomic. For now I left them the same as the RFC patch - using counter_atomic32 -- Unrelated to this patch series: The patch series review uncovered improvements could be made to test_async_driver_probe and vmw_vmci/vmci_guest. I will track these for fixing later.
Shuah Khan (11): counters: Introduce counter_simple* and counter_atomic* counters selftests:lib:test_counters: add new test for counters drivers/base: convert deferred_trigger_count and probe_count to counter_atomic32 drivers/base/devcoredump: convert devcd_count to counter_atomic32 drivers/acpi: convert seqno counter_atomic32 drivers/acpi/apei: convert seqno counter_atomic32 drivers/android/binder: convert stats, transaction_log to counter_atomic32 drivers/base/test/test_async_driver_probe: convert to use counter_atomic32 drivers/char/ipmi: convert stats to use counter_atomic32 drivers/misc/vmw_vmci: convert num guest devices counter to counter_atomic32 drivers/edac: convert pci counters to counter_atomic32
Documentation/core-api/counters.rst | 174 +++++++++ MAINTAINERS | 8 + drivers/acpi/acpi_extlog.c | 5 +- drivers/acpi/apei/ghes.c | 5 +- drivers/android/binder.c | 41 +-- drivers/android/binder_internal.h | 3 +- drivers/base/dd.c | 19 +- drivers/base/devcoredump.c | 5 +- drivers/base/test/test_async_driver_probe.c | 23 +- drivers/char/ipmi/ipmi_msghandler.c | 9 +- drivers/char/ipmi/ipmi_si_intf.c | 9 +- drivers/edac/edac_pci.h | 5 +- drivers/edac/edac_pci_sysfs.c | 28 +- drivers/misc/vmw_vmci/vmci_guest.c | 9 +- include/linux/counters.h | 350 +++++++++++++++++++ lib/Kconfig | 10 + lib/Makefile | 1 + lib/test_counters.c | 276 +++++++++++++++ tools/testing/selftests/lib/Makefile | 1 + tools/testing/selftests/lib/config | 1 + tools/testing/selftests/lib/test_counters.sh | 5 + 21 files changed, 913 insertions(+), 74 deletions(-) create mode 100644 Documentation/core-api/counters.rst create mode 100644 include/linux/counters.h create mode 100644 lib/test_counters.c create mode 100755 tools/testing/selftests/lib/test_counters.sh
-- 2.25.1