Commit aea4869f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull core fixes from Ingo Molnar:
 "The tree contains two RCU fixes and a compiler quirk comment fix"

* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  rcu: Make rcu_barrier() understand about missing rcuo kthreads
  compiler/gcc4+: Remove inaccurate comment about 'asm goto' miscompiles
  rcu: More on deadlock between CPU hotplug and expedited grace periods
parents 0f4b0676 21ee24bf
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -71,7 +71,6 @@
 *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
 *
 * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
 * Fixed in GCC 4.8.2 and later versions.
 *
 * (asm goto is automatically volatile - the naming reflects this.)
 */
+0 −1
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@
 *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
 *
 * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
 * Fixed in GCC 4.8.2 and later versions.
 *
 * (asm goto is automatically volatile - the naming reflects this.)
 */
+9 −9
Original line number Diff line number Diff line
@@ -660,18 +660,18 @@ TRACE_EVENT(rcu_torture_read,
/*
 * Tracepoint for _rcu_barrier() execution.  The string "s" describes
 * the _rcu_barrier phase:
 *	"Begin": rcu_barrier_callback() started.
 *	"Check": rcu_barrier_callback() checking for piggybacking.
 *	"EarlyExit": rcu_barrier_callback() piggybacked, thus early exit.
 *	"Inc1": rcu_barrier_callback() piggyback check counter incremented.
 *	"Offline": rcu_barrier_callback() found offline CPU
 *	"OnlineNoCB": rcu_barrier_callback() found online no-CBs CPU.
 *	"OnlineQ": rcu_barrier_callback() found online CPU with callbacks.
 *	"OnlineNQ": rcu_barrier_callback() found online CPU, no callbacks.
 *	"Begin": _rcu_barrier() started.
 *	"Check": _rcu_barrier() checking for piggybacking.
 *	"EarlyExit": _rcu_barrier() piggybacked, thus early exit.
 *	"Inc1": _rcu_barrier() piggyback check counter incremented.
 *	"OfflineNoCB": _rcu_barrier() found callback on never-online CPU
 *	"OnlineNoCB": _rcu_barrier() found online no-CBs CPU.
 *	"OnlineQ": _rcu_barrier() found online CPU with callbacks.
 *	"OnlineNQ": _rcu_barrier() found online CPU, no callbacks.
 *	"IRQ": An rcu_barrier_callback() callback posted on remote CPU.
 *	"CB": An rcu_barrier_callback() invoked a callback, not the last.
 *	"LastCB": An rcu_barrier_callback() invoked the last callback.
 *	"Inc2": rcu_barrier_callback() piggyback check counter incremented.
 *	"Inc2": _rcu_barrier() piggyback check counter incremented.
 * The "cpu" argument is the CPU or -1 if meaningless, the "cnt" argument
 * is the count of remaining callbacks, and "done" is the piggybacking count.
 */
+13 −1
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ static struct {
	 * an ongoing cpu hotplug operation.
	 */
	int refcount;
	/* And allows lockless put_online_cpus(). */
	atomic_t puts_pending;

#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map dep_map;
@@ -113,7 +115,11 @@ void put_online_cpus(void)
{
	if (cpu_hotplug.active_writer == current)
		return;
	mutex_lock(&cpu_hotplug.lock);
	if (!mutex_trylock(&cpu_hotplug.lock)) {
		atomic_inc(&cpu_hotplug.puts_pending);
		cpuhp_lock_release();
		return;
	}

	if (WARN_ON(!cpu_hotplug.refcount))
		cpu_hotplug.refcount++; /* try to fix things up */
@@ -155,6 +161,12 @@ void cpu_hotplug_begin(void)
	cpuhp_lock_acquire();
	for (;;) {
		mutex_lock(&cpu_hotplug.lock);
		if (atomic_read(&cpu_hotplug.puts_pending)) {
			int delta;

			delta = atomic_xchg(&cpu_hotplug.puts_pending, 0);
			cpu_hotplug.refcount -= delta;
		}
		if (likely(!cpu_hotplug.refcount))
			break;
		__set_current_state(TASK_UNINTERRUPTIBLE);
+10 −5
Original line number Diff line number Diff line
@@ -3299,11 +3299,16 @@ static void _rcu_barrier(struct rcu_state *rsp)
			continue;
		rdp = per_cpu_ptr(rsp->rda, cpu);
		if (rcu_is_nocb_cpu(cpu)) {
			if (!rcu_nocb_cpu_needs_barrier(rsp, cpu)) {
				_rcu_barrier_trace(rsp, "OfflineNoCB", cpu,
						   rsp->n_barrier_done);
			} else {
				_rcu_barrier_trace(rsp, "OnlineNoCB", cpu,
						   rsp->n_barrier_done);
				atomic_inc(&rsp->barrier_cpu_count);
			__call_rcu(&rdp->barrier_head, rcu_barrier_callback,
				   rsp, cpu, 0);
				__call_rcu(&rdp->barrier_head,
					   rcu_barrier_callback, rsp, cpu, 0);
			}
		} else if (ACCESS_ONCE(rdp->qlen)) {
			_rcu_barrier_trace(rsp, "OnlineQ", cpu,
					   rsp->n_barrier_done);
Loading