[RFC] WRITE_ONCE_INC() and friends

From: Petko Manolov
Date: Sun Apr 19 2020 - 05:44:48 EST


Hi Paul,

Recently I started reading up on KCSAN and at some point I ran into stuff like:

WRITE_ONCE(ssp->srcu_lock_nesting[idx], ssp->srcu_lock_nesting[idx] + 1);
WRITE_ONCE(p->mm->numa_scan_seq, READ_ONCE(p->mm->numa_scan_seq) + 1);

Some of these are a bit eye-watering for me and could easily be converted to:

WRITE_ONCE_INC(ssp->srcu_lock_nesting[idx]);
WRITE_ONCE_INC(p->mm->numa_scan_seq);

where the above macro could be either:

#define WRITE_ONCE_INC(x) WRITE_ONCE(x, READ_ONCE(x) + 1)

or the more relaxed version:

#define WRITE_ONCE_INC(x) WRITE_ONCE(x, x + 1)

I personally like the stronger version better as a) it doesn't seem to increase
code size (relative to the relaxed one), and b) should be less prone to load
tearing, etc. Given the growing popularity of KCSAN I expect a lot of
concurrent code soon will get the READ_ONCE/WRITE_ONCE conversion.

If you think the above makes sense we could also do this:

#define WRITE_ONCE_DEC(x) WRITE_ONCE(x, READ_ONCE(x) - 1)
#define WRITE_ONCE_ADD(x, v) WRITE_ONCE(x, READ_ONCE(x) + v)
#define WRITE_ONCE_SUB(x, v) WRITE_ONCE(x, READ_ONCE(x) - v)


cheers,
Petko