On Thu, Jan 28, 2021 at 11:12:28AM -0800, Paul E. McKenney wrote:
On Thu, Jan 28, 2021 at 06:12:10PM +0100, Frederic Weisbecker wrote:
Simply checking if the segcblist is enabled is enough to know if we need to initialize it or not. It's safe to check within hotplug machine.
Signed-off-by: Frederic Weisbecker frederic@kernel.org Cc: Josh Triplett josh@joshtriplett.org Cc: Lai Jiangshan jiangshanlai@gmail.com Cc: Joel Fernandes joel@joelfernandes.org Cc: Neeraj Upadhyay neeraju@codeaurora.org Cc: Boqun Feng boqun.feng@gmail.com
Hmmm...
At the start of a CPU-hotplug operation, an incoming CPU's callback list can be in a number of states:
Disabled and empty. This is the case when the boot CPU has not done call_rcu(), when a non-boot CPU first comes online, and when a non-offloaded CPU comes back online. In this case, it is permissible to initialize ->cblist. Because either the CPU is currently running with interrupts disabled (boot CPU) or is not yet running at all (other CPUs), it is not necessary to acquire ->nocb_lock.
Disabled and non-empty. This is the case when the boot CPU has done call_rcu(). It is not permissible to initialize ->cblist because doing so will leak any callbacks posted by early boot invocations of call_rcu().
I don't think that's possible. In this case __call_rcu() has called rcu_segcblist_init() and has enabled the segcblist.
Test for the possibility of leaking by building with CONFIG_PROVE_RCU=y and booting with rcupdate.rcu_self_test=1.
- Enabled, whether empty or not. This is the case when an offloaded CPU comes back online. This is the only case where the ->nocb_lock must be held to modify ->cblist. However, it is not necessarily to modify ->cblist because the rcuoc kthread is on the job.
So I believe that it is necessary to check for both disabled and empty. But don't take my word for it! Build with CONFIG_PROVE_RCU=y and boot with rcupdate.rcu_self_test=1. ;-)
I'm trying that :-)