Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 143da9c2 authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

rcu: Prevent early-boot RCU callbacks from splatting



Currently, a call_rcu() that precedes rcu_init() will splat due to the
callback lists not having yet been initialized.  This commit causes the
first such callback to initialize the boot CPU's RCU callback list.

Note that this commit does not change rcu_init()-time initialization,
which means that the callback will be discarded at rcu_init() time.
Fixing this is the job of later commits.

Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 2723249a
Loading
Loading
Loading
Loading
+15 −5
Original line number Original line Diff line number Diff line
@@ -2838,12 +2838,22 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),


		if (cpu != -1)
		if (cpu != -1)
			rdp = per_cpu_ptr(rsp->rda, cpu);
			rdp = per_cpu_ptr(rsp->rda, cpu);
		if (likely(rdp->mynode)) {
			/* Post-boot, so this should be for a no-CBs CPU. */
			offline = !__call_rcu_nocb(rdp, head, lazy, flags);
			offline = !__call_rcu_nocb(rdp, head, lazy, flags);
			WARN_ON_ONCE(offline);
			WARN_ON_ONCE(offline);
		/* _call_rcu() is illegal on offline CPU; leak the callback. */
			/* Offline CPU, _call_rcu() illegal, leak callback.  */
			local_irq_restore(flags);
			local_irq_restore(flags);
			return;
			return;
		}
		}
		/*
		 * Very early boot, before rcu_init().  Initialize if needed
		 * and then drop through to queue the callback.
		 */
		BUG_ON(cpu != -1);
		if (!likely(rdp->nxtlist))
			init_default_callback_list(rdp);
	}
	ACCESS_ONCE(rdp->qlen) = rdp->qlen + 1;
	ACCESS_ONCE(rdp->qlen) = rdp->qlen + 1;
	if (lazy)
	if (lazy)
		rdp->qlen_lazy++;
		rdp->qlen_lazy++;