• Marco Elver's avatar
    kcsan: permissive: Ignore data-racy 1-bit value changes · d8fd74d3
    Marco Elver authored
    Add rules to ignore data-racy reads with only 1-bit value changes.
    Details about the rules are captured in comments in
    kernel/kcsan/permissive.h. More background follows.
    
    While investigating a number of data races, we've encountered data-racy
    accesses on flags variables to be very common. The typical pattern is a
    reader masking all but one bit, and/or the writer setting/clearing only
    1 bit (current->flags being a frequently encountered case; more examples
    in mm/sl[au]b.c, which disable KCSAN for this reason).
    
    Since these types of data-racy accesses are common (with the assumption
    they are intentional and hard to miscompile) having the option (with
    CONFIG_KCSAN_PERMISSIVE=y) to filter them will avoid forcing everyone to
    mark them, and deliberately left to preference at this time.
    
    One important motivation for having this option built-in is to move
    closer to being able to enable KCSAN on CI systems or for testers
    wishing to test the whole kernel, while more easily filtering
    less interesting data races with higher probability.
    
    For the implementation, we considered several alternatives, but had one
    major requirement: that the rules be kept together with the Linux-kernel
    tree. Adding them to the compiler would preclude us from making changes
    quickly; if the rules require tweaks, having them part of the compiler
    requires waiting another ~1 year for the next release -- that's not
    realistic. We are left with the following options:
    
    	1. Maintain compiler plugins as part of the kernel-tree that
    	   removes instrumentation for some accesses (e.g. plain-& with
    	   1-bit mask). The analysis would be reader-side focused, as
    	   no assumption can be made about racing writers.
    
    Because it seems unrealistic to maintain 2 plugins, one for LLVM and
    GCC, we would likely pick LLVM. Furthermore, no kernel infrastructure
    exists to maintain LLVM plugins, and the build-system implications and
    maintenance overheads do not look great (historically, plugins written
    against old LLVM APIs are not guaranteed to work with newer LLVM APIs).
    
    	2. Find a set of rules that can be expressed in terms of
    	   observed value changes, and make it part of the KCSAN runtime.
    	   The analysis is writer-side focused, given we rely on observed
    	   value changes.
    
    The approach taken here is (2). While a complete approach requires both
    (1) and (2), experiments show that the majority of data races involving
    trivial bit operations on flags variables can be removed with (2) alone.
    
    It goes without saying that the filtering of data races using (1) or (2)
    does _not_ guarantee they are safe! Therefore, limiting ourselves to (2)
    for now is the conservative choice for setups that wish to enable
    CONFIG_KCSAN_PERMISSIVE=y.
    Signed-off-by: default avatarMarco Elver <elver@google.com>
    Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    d8fd74d3
kcsan_test.c 35.2 KB