Re: [PATCH 1/1] kernel/locking: Add mutual exclusion self-test
From: David Laight
Date: Mon Sep 14 2026 - 17:41:01 EST
On Mon, 14 Sep 2026 17:21:41 +0000
Haakon Bugge <haakon.bugge@xxxxxxxxxx> wrote:
> > On 14 Sep 2026, at 14:32, Haakon Bugge <haakon.bugge@xxxxxxxxxx> wrote:
> >
> > On 14 Sep 2026, at 11:35, David Laight <david.laight.linux@xxxxxxxxx> wrote:
>
> [snip]
>
> >> If you use change the MX_ATOMIC_ADD to use the atomic_long functions
> >> (I've forgotten the exact name) then all the counter are the same type
> >> and can be removed from the union.
> >> The default 'just use +=' code can then be moved to the bottom of mx_add().
> >
> > That is a good idea, but we then misses test coverage for atomic_t. But,
> > what about:
>
> [snip]
>
> I ended up with:
>
> struct mx_elem {
> /* This union contains locks and lock-free data types */
> union {
> spinlock_t spinlock;
> rwlock_t rwlock;
> struct mutex mutex;
> atomic_t atomic_lock;
> atomic_t atomic_counter;
> atomic64_t atomic64_counter;
> long cmpxchg_counter;
> unsigned long bits;
> struct ww_mutex ww_mutex;
> struct optimistic_spin_queue osq_lock;
> };
> /* A counter protected by one of the locks above */
> long counter;
> };
>
> This became quite simpler. I'll test somewhat more, and send out
> a v2 tomorrow.
If you split the 'long counter' into a separate array then it won't
be in the same cache line as the associated lock.
That should mean the alignment changes aren't needed.
When I mentioned a delay in the RMW for xxx->counter++ I was thinking
of a few clocks, perhaps something like:
c = xxx->counter;
for (auto i = c + 10; i != c; i--)
OPTIMIZER_HIDE_VAR(i);
OPTIMIZER_HIDE_VAR(i);
xxx->counter = i + delta;
I may have a '3am can't sleep' part model for the arm cache.
It might be that when one cpu writes to a 'shared' cache line the 'invalidate'
that is broadcast is only partial; the invalidate is remembered, but the
contents of the cache line are still used to satisfy reads.
So a memory read for a different cache line could easily pick up a write
that was done later.
A read barrier actually invalidates all the 'invalidated' cache lines
so later reads can't use the 'stale' data.
Just need a model for the write barrier now.
It might just that each 'cache line wide' entry in the store buffer fifo
can have multiple addresses associated with different groups of writes.
Then the writes for one fifo entry could happen in any order (or be
merged into a single wider write.
(But that is real guesswork.)
It is nice to a have a simple model that mostly matches the observed
behaviour.
David
>
>
> Thxs, Håkon
>