Re: [RFC PATCH 12/12] samples: Add a cache on RCU pseudo-transactions with a lock per node

From: Puranjay Mohan

Date: Fri Oct 23 2026 - 14:24:58 EST


On Fri, Oct 16, 2026 at 09:33:19AM -0400, Mathieu Desnoyers wrote:
[...]

> + rcu_read_lock();
> + e = lru_entry(rcu_txn_list_prev_rcu(&cache_lru.head.node));
> + if (!e) {
> + rcu_read_unlock();
> + rcu_txn_cancel(&txn);
> + break;
> + }
> + if (chances < CACHE_CHANCES && READ_ONCE(e->referenced)) {
> + WRITE_ONCE(e->referenced, false);
> + cache_move_front(&txn, e);
> + chances++;
> + } else {
> + evicted = __cache_unlink(&txn, e->key, e, NULL);

I think there's an eviction race here. cache_lock_entry() re-plans
from e's current links, but doesn't check that e is still the tail. If
W1 gives e a second chance (clears referenced, moves it to the front)
while W2 has already read e as the tail, W2 then sees referenced
cleared, locks e at the front and evicts the entry W1 just saved. Only
the policy suffers. Checking p->next == &cache_lru.head.node for
evictions would close it, but then cache_lock_entry() has to return
false when the check fails rather than retry, or the writer spins until
e is back at the tail.

[...]

> + atomic_long_inc(&nr_lost); /* another writer was first */
> + kfree(new);

Nit: an allocation failure in cache_unlink() or cache_link() also ends
up here, so it's counted as a lost race as well as a failure.

Two more small things, which apply to the mutex sample in patch 11 as
well: a bad lookup (nr_bad) prints the same "the hash table and the list
disagree" as a cache_check() failure, and a kthread_run() failure is
skipped silently, so a run in which no thread started reports no error.

Thanks,
Puranjay