mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Puranjay Mohan <puranjay@kernel.org>
Cc: "Paul E . McKenney" <paulmck@kernel.org>,
	linux-kernel@vger.kernel.org, Boqun Feng <boqun@kernel.org>,
	Josh Triplett <josh@joshtriplett.org>,
	Frederic Weisbecker <frederic@kernel.org>,
	Neeraj Upadhyay <neeraj.upadhyay@kernel.org>,
	Joel Fernandes <joelagnelf@nvidia.com>,
	Uladzislau Rezki <urezki@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Lai Jiangshan <jiangshanlai@gmail.com>,
	Zqiang <qiang.zhang@linux.dev>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Matthew Wilcox <willy@infradead.org>,
	Christian Brauner <brauner@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Liam R . Howlett" <liam@infradead.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	Alice Ryhl <aliceryhl@google.com>,
	Andrew Ballance <andrewjballance@gmail.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Will Deacon <will@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Ingo Molnar <mingo@kernel.org>, Thomas Gleixner <tglx@kernel.org>,
	rcu@vger.kernel.org
Subject: Re: [RFC PATCH 00/12] RCU pseudo-transactions
Date: Tue, 10 Nov 2026 10:11:12 -0500	[thread overview]
Message-ID: <ba93b677-ab72-4a85-a7d4-a77aef6dc746@efficios.com> (raw)
In-Reply-To: <20261023181940.457424-1-puranjay@kernel.org>

Hi Puranjay,

On 2026-10-23 14:19, Puranjay Mohan wrote:
[...]
> I found two bugs, details in the replies to the patches:

Thanks for finding them, and for the reproducers. Fixes for both bugs
are planned for the next version. I answered each point of your patch
replies in its own thread. Here are the answers to the rest of this
mail.

> Location: either works for me, but CONFIG_RCU_TXN is in lib/Kconfig and
> CONFIG_DEBUG_RCU_TXN in kernel/rcu/Kconfig.debug; I'd keep them
> together.

Planned for the next version. DEBUG_RCU_TXN will move to
lib/Kconfig.debug, next to RCU_TXN_KUNIT_TEST.

> Bloom filter knob: I wouldn't add one.
[...]
> I'd drop patch 3 until something needs it.

Agreed. Dropping patch 3 is planned for the next version. Your size
table settled it.

> API shape: every rcu_txn_list add, delete and replace allocates a
> descriptor and frees it with kfree_rcu(), so all of them can fail with
> -ENOMEM, delete included.  That is hard to use on teardown paths, and
> reserving first only moves the failure.  Since a descriptor can be
> reused a grace period after its commit, have you considered a small
> cache of them, tagged with start_poll_synchronize_rcu() and checked with
> poll_state_synchronize_rcu()?

The next version will implement the design of my second reply. It is
planned as three new patches:

- Readers resolve a proxy only within a resolve section. This
   is a short section with interrupts off, counted per CPU. A writer can
   wait for the sections in flight without sleeping.
- A local transaction takes its descriptor from a per-CPU
   pool. The pool holds 16 descriptors of 6 records, 5920 bytes per CPU.
   Preemption stays off from init to commit.
- The _rcu forms of rcu_txn_list run a local transaction. They take
   no gfp_t and return nothing.

A cache alone does not cover a burst. A CPU can run more operations
within a grace period than its pool holds. When its pool is empty, the
CPU steals its own descriptors back. It waits for the resolve sections
in flight, then reuses them. So a delete never fails and never sleeps.

In the steady state, descriptors go back to the pool through
call_rcu_hurry(), with one rcu_head per batch. With CONFIG_RCU_LAZY,
call_rcu() can hold a callback back for up to 10 seconds. The
descriptors would stay out of the pool that long, and the CPU would
steal more often. I chose a callback over start_poll_synchronize_rcu()
because start_poll takes the leaf rcu_node lock on every call.

> Separately, a one-record transaction
> never installs a proxy but still allocates a descriptor, 256 bytes
> unless reserved smaller; keeping the first record inline in struct
> rcu_txn would avoid that.

I would rather handle this in the users than in rcu_txn. A user knows
which of the pointers it writes are followed by readers. An update that
re-points a single such slot needs no transaction. The writers are
excluded, and every commit settles its slots before it returns, so the
slot holds no proxy. rcu_assign_pointer() then publishes the update.

This covers more than one-record transactions. Each _rcu operation of
rcu_txn_hlist writes several pointers, but readers follow only one
edge. That edge is published with rcu_assign_pointer(), and pprev and
the new node's links take plain stores. So none of them creates a
transaction. Recorded through rcu_txn, the same update would take two
or three records, and an inline first record would not cover it.
Patch 7 documents this in Documentation/RCU/rcu_txn.rst.

The rcu_txn_list operations change at least two slots that readers
follow, so they need a descriptor. With the pool, they will allocate
nothing either.

> Subsystems: in dcache the hash buckets are hlist_bl, with bit 0 of the
> head as the lock, and d_unhashed() tests for a NULL pprev.
> rcu_txn_hlist hard-codes bit 0 as its tag and has no unhashed state, so
> I'm curious how your userspace port deals with both.

The hlist of this series is for tables locked some other way, as in the
samples. A bucket with a bit lock gets an rcu_txn_hlist_bl:

- The lock keeps bit 0, as in list_bl.h.
- The proxy tag takes bit 1.
- A record of the head carries the lock bit in its tag and in both of
   its values. So the head stays locked from install to settle.
- Readers strip the lock bit. The engine is unchanged.

It is not part of this series. It exists on my branch that converts
the dentry cache to rcu_txn. The userspace port does the same with
other bits: tag in bit 0, lock in bit 2.

For d_unhashed(), the unhashed state you asked for in patch 5 is
planned for the next version. A removed node will have a NULL pprev.

> Also, the only
> in-tree user of list_bidir_prev_rcu(), kernel/nstree.c, walks either way
> but never forward and then back in one walk, so a user that needs that
> guarantee would help make the case for patch 6.

The node-lock sample (patch 12) is such a user. An eviction walks
back from the head to the tail. Then cache_lock_entry() reads the
tail's prev and next, to lock its neighbours. cache_plan_holds()
re-checks the four edges in both directions. If the backward chain
disagreed with the forward one, the writer would lock the wrong nodes.
Your reply to patch 6 makes the same point about LRU second chances.

> I can send my KUnit reproducers as patches if they're useful.

Yes, please. They can go on top of the next version.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com

      parent reply	other threads:[~2026-11-10 15:11 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 13:33 Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 01/12] rcu_txn: Add single-writer " Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:11     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 02/12] rcu_txn: Add KUnit tests Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 03/12] rcu_txn: Skip the record lookup with a Bloom filter Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:12     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 04/12] rcu_txn: Add CONFIG_DEBUG_RCU_TXN Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:12     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 05/12] rcu_txn: Add an hlist edited through transactions Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:12     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 06/12] rcu_txn: Add a doubly-linked list coherent in both directions Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:13     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 07/12] Documentation/RCU: Describe RCU pseudo-transactions Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 08/12] Documentation/litmus-tests: Add RCU pseudo-transaction tests Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 09/12] rcu_txn: Test a list writer against concurrent readers Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:13     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 10/12] rcu_txn: Test a commit from atomic context Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:14     ` Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 11/12] samples: Add a cache on RCU pseudo-transactions under one mutex Mathieu Desnoyers
2026-10-16 13:33 ` [RFC PATCH 12/12] samples: Add a cache on RCU pseudo-transactions with a lock per node Mathieu Desnoyers
2026-10-23 18:22   ` Puranjay Mohan
2026-11-10 15:14     ` Mathieu Desnoyers
2026-10-19  0:55 ` [RFC PATCH 00/12] RCU pseudo-transactions Joel Fernandes
2026-10-23 13:37   ` Mathieu Desnoyers
2026-10-23 18:19 ` Puranjay Mohan
2026-10-27 19:57   ` Mathieu Desnoyers
2026-10-28  1:13     ` Mathieu Desnoyers
2026-11-10  0:25       ` Paul E. McKenney
2026-11-10  1:00         ` Mathieu Desnoyers
2026-11-10  1:34           ` Paul E. McKenney
2026-11-10 15:26             ` Mathieu Desnoyers
2026-11-10 15:11   ` Mathieu Desnoyers [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ba93b677-ab72-4a85-a7d4-a77aef6dc746@efficios.com \
    --to=mathieu.desnoyers@efficios.com \
    --cc=aliceryhl@google.com \
    --cc=andrewjballance@gmail.com \
    --cc=boqun@kernel.org \
    --cc=brauner@kernel.org \
    --cc=frederic@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jiangshanlai@gmail.com \
    --cc=joelagnelf@nvidia.com \
    --cc=josh@joshtriplett.org \
    --cc=liam@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@kernel.org \
    --cc=neeraj.upadhyay@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=puranjay@kernel.org \
    --cc=qiang.zhang@linux.dev \
    --cc=rcu@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=urezki@gmail.com \
    --cc=will@kernel.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®