[PATCH 0/6] Rework REFCOUNT_FULL using atomic_fetch_* operations

From: Will Deacon
Date: Fri Aug 02 2019 - 06:10:08 EST


Hi all,

This patch series reworks the generic REFCOUNT_FULL implementation using
atomic_fetch_* operations so that the performance impact of the cmpxchg()
loops is mitigated for common refcount operations. The algorithm was
heavily inspired by Ard's assembly implementation for arm64:

http://lkml.kernel.org/r/20190619105431.2630-1-ard.biesheuvel@xxxxxxxxxx

but I figured we could achieve something similar using atomics in generic
code.

Although the revised implementation passes all of the lkdtm REFCOUNT
tests, there is a race condition introduced by the deferred saturation
whereby if INT_MIN + 2 tasks take a reference on a refcount at
REFCOUNT_MAX and are each preempted between detecting overflow and
writing the saturated value without being rescheduled, then another task
may end up erroneously freeing the object when it drops the refcount and
sees zero. It doesn't feel like a particularly realistic case to me, but
I thought I should mention it in case somebody else knows better.

Will

Cc: Kees Cook <keescook@xxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Elena Reshetova <elena.reshetova@xxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
Cc: Hanjun Guo <guohanjun@xxxxxxxxxx>
Cc: Jan Glauber <jglauber@xxxxxxxxxxx>

--->8

Will Deacon (6):
lib/refcount: Define constants for saturation and max refcount values
lib/refcount: Ensure integer operands are treated as signed
lib/refcount: Remove unused refcount_*_checked() variants
lib/refcount: Move bulk of REFCOUNT_FULL implementation into header
lib/refcount: Improve performance of generic REFCOUNT_FULL code
lib/refcount: Consolidate REFCOUNT_{MAX,SATURATED} definitions

drivers/misc/lkdtm/refcount.c | 8 --
include/linux/refcount.h | 236 +++++++++++++++++++++++++++++++++++++----
lib/refcount.c | 238 +-----------------------------------------
3 files changed, 219 insertions(+), 263 deletions(-)

--
2.11.0