summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-generic6
-rw-r--r--config-nodebug114
-rw-r--r--config-x86-generic2
-rw-r--r--kernel.spec15
-rw-r--r--rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch177
-rw-r--r--rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch67
-rw-r--r--sources1
7 files changed, 319 insertions, 63 deletions
diff --git a/config-generic b/config-generic
index acd9cc340..487fd7cb0 100644
--- a/config-generic
+++ b/config-generic
@@ -1699,13 +1699,13 @@ CONFIG_B43_PCMCIA=y
CONFIG_B43_SDIO=y
CONFIG_B43_BCMA=y
CONFIG_B43_BCMA_PIO=y
-# CONFIG_B43_DEBUG is not set
+CONFIG_B43_DEBUG=y
CONFIG_B43_PHY_LP=y
CONFIG_B43_PHY_N=y
CONFIG_B43_PHY_HT=y
CONFIG_B43_PHY_G=y
CONFIG_B43LEGACY=m
-# CONFIG_B43LEGACY_DEBUG is not set
+CONFIG_B43LEGACY_DEBUG=y
CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
@@ -4694,7 +4694,7 @@ CONFIG_PM_DEBUG=y
# CONFIG_DPM_WATCHDOG is not set # revisit this in debug
CONFIG_PM_TRACE=y
CONFIG_PM_TRACE_RTC=y
-# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_PM_TEST_SUSPEND=y
CONFIG_PM_RUNTIME=y
# CONFIG_PM_OPP is not set
# CONFIG_PM_AUTOSLEEP is not set
diff --git a/config-nodebug b/config-nodebug
index ed6913376..143433bf8 100644
--- a/config-nodebug
+++ b/config-nodebug
@@ -2,115 +2,115 @@ CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_PCM_XRUN_DEBUG=y
-# CONFIG_DEBUG_ATOMIC_SLEEP is not set
-
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_LOCK_TORTURE_TEST is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_PROVE_RCU is not set
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_LOCK_TORTURE_TEST=m
+CONFIG_PROVE_LOCKING=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_PROVE_RCU=y
# CONFIG_PROVE_RCU_REPEATEDLY is not set
-# CONFIG_DEBUG_PER_CPU_MAPS is not set
+CONFIG_DEBUG_PER_CPU_MAPS=y
CONFIG_CPUMASK_OFFSTACK=y
-# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
+CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_FAILSLAB is not set
-# CONFIG_FAIL_PAGE_ALLOC is not set
-# CONFIG_FAIL_MAKE_REQUEST is not set
-# CONFIG_FAULT_INJECTION_DEBUG_FS is not set
-# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set
-# CONFIG_FAIL_IO_TIMEOUT is not set
-# CONFIG_FAIL_MMC_REQUEST is not set
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAIL_MAKE_REQUEST=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_FAIL_IO_TIMEOUT=y
+CONFIG_FAIL_MMC_REQUEST=y
-# CONFIG_LOCK_STAT is not set
+CONFIG_LOCK_STAT=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_STACK_USAGE=y
-# CONFIG_ACPI_DEBUG is not set
+CONFIG_ACPI_DEBUG=y
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_PI_LIST is not set
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_PI_LIST=y
# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_OBJECTS is not set
+CONFIG_DEBUG_OBJECTS=y
# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
-# CONFIG_DEBUG_OBJECTS_FREE is not set
-# CONFIG_DEBUG_OBJECTS_TIMERS is not set
-# CONFIG_DEBUG_OBJECTS_RCU_HEAD is not set
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
-# CONFIG_X86_PTDUMP is not set
-# CONFIG_EFI_PGT_DUMP is not set
+CONFIG_X86_PTDUMP=y
+CONFIG_EFI_PGT_DUMP=y
-# CONFIG_CAN_DEBUG_DEVICES is not set
+CONFIG_CAN_DEBUG_DEVICES=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_DEBUG_NOTIFIERS=y
-# CONFIG_DMA_API_DEBUG is not set
+CONFIG_DMA_API_DEBUG=y
-# CONFIG_MMIOTRACE is not set
+CONFIG_MMIOTRACE=y
-# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_DEBUG_CREDENTIALS=y
# off in both production debug and nodebug builds,
# on in rawhide nodebug builds
-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
-# CONFIG_EXT4_DEBUG is not set
+CONFIG_EXT4_DEBUG=y
# CONFIG_XFS_WARN is not set
-# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_DEBUG_PERF_USE_VMALLOC=y
-# CONFIG_JBD2_DEBUG is not set
+CONFIG_JBD2_DEBUG=y
-# CONFIG_NFSD_FAULT_INJECTION is not set
+CONFIG_NFSD_FAULT_INJECTION=y
-# CONFIG_DEBUG_BLK_CGROUP is not set
+CONFIG_DEBUG_BLK_CGROUP=y
-# CONFIG_DRBD_FAULT_INJECTION is not set
+CONFIG_DRBD_FAULT_INJECTION=y
-# CONFIG_ATH_DEBUG is not set
-# CONFIG_CARL9170_DEBUGFS is not set
-# CONFIG_IWLWIFI_DEVICE_TRACING is not set
+CONFIG_ATH_DEBUG=y
+CONFIG_CARL9170_DEBUGFS=y
+CONFIG_IWLWIFI_DEVICE_TRACING=y
# CONFIG_RTLWIFI_DEBUG is not set
-# CONFIG_DEBUG_OBJECTS_WORK is not set
+CONFIG_DEBUG_OBJECTS_WORK=y
-# CONFIG_DMADEVICES_DEBUG is not set
-# CONFIG_DMADEVICES_VDEBUG is not set
+CONFIG_DMADEVICES_DEBUG=y
+CONFIG_DMADEVICES_VDEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y
-# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
-# CONFIG_QUOTA_DEBUG is not set
+CONFIG_CEPH_LIB_PRETTYDEBUG=y
+CONFIG_QUOTA_DEBUG=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
CONFIG_KDB_CONTINUE_CATASTROPHIC=0
-# CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER is not set
+CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
# CONFIG_PERCPU_TEST is not set
-# CONFIG_TEST_LIST_SORT is not set
+CONFIG_TEST_LIST_SORT=y
# CONFIG_TEST_STRING_HELPERS is not set
-# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
-# CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set
+CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
-# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=1024
# CONFIG_DEBUG_KMEMLEAK_TEST is not set
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
@@ -121,7 +121,7 @@ CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
# CONFIG_SPI_DEBUG is not set
-# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
+CONFIG_X86_DEBUG_STATIC_CPU_HAS=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_LATENCYTOP is not set
diff --git a/config-x86-generic b/config-x86-generic
index 59217f12b..2a12307ea 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -337,7 +337,7 @@ CONFIG_SP5100_TCO=m
# CONFIG_MEMTEST is not set
# CONFIG_DEBUG_TLBFLUSH is not set
-# CONFIG_MAXSMP is not set
+CONFIG_MAXSMP=y
CONFIG_HP_ILO=m
diff --git a/kernel.spec b/kernel.spec
index eceb18a2e..f5a45f24d 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -69,7 +69,7 @@ Summary: The Linux kernel
# The rc snapshot level
%define rcrev 2
# The git snapshot level
-%define gitrev 0
+%define gitrev 1
# Set rpm version accordingly
%define rpmversion 3.%{upstream_sublevel}.0
%endif
@@ -124,7 +124,7 @@ Summary: The Linux kernel
# Set debugbuildsenabled to 1 for production (build separate debug kernels)
# and 0 for rawhide (all kernels are debug kernels).
# See also 'make debug' and 'make release'.
-%define debugbuildsenabled 1
+%define debugbuildsenabled 0
# Want to build a vanilla kernel build without any non-upstream patches?
%define with_vanilla %{?_with_vanilla: 1} %{?!_with_vanilla: 0}
@@ -620,6 +620,9 @@ Patch26058: asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
#rhbz 1111138
Patch26059: i8042-Add-notimeout-quirk-for-Fujitsu-Lifebook-A544-.patch
+Patch26060: rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch
+Patch26061: rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch
+
# git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel
Patch30000: kernel-arm64.patch
@@ -1349,6 +1352,9 @@ ApplyPatch asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
#rhbz 1111138
ApplyPatch i8042-Add-notimeout-quirk-for-Fujitsu-Lifebook-A544-.patch
+ApplyPatch rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch
+ApplyPatch rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch
+
%if 0%{?aarch64patches}
ApplyPatch kernel-arm64.patch
%ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does.
@@ -2217,6 +2223,11 @@ fi
# ||----w |
# || ||
%changelog
+* Tue Oct 28 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.18.0-0.rc2.git1.1
+- Linux v3.18-rc2-43-gf7e87a44ef60
+- Add two RCU patches to fix a deadlock and a hang
+- Reenable debugging options.
+
* Mon Oct 27 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.18.0-0.rc2.git0.1
- Linux v3.18-rc2
- Disable debugging options.
diff --git a/rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch b/rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch
new file mode 100644
index 000000000..ca3592e53
--- /dev/null
+++ b/rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch
@@ -0,0 +1,177 @@
+From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Date: Mon, 27 Oct 2014 09:15:54 -0700
+Subject: [PATCH] rcu: Make rcu_barrier() understand about missing rcuo
+ kthreads
+
+Commit 35ce7f29a44a (rcu: Create rcuo kthreads only for onlined CPUs)
+avoids creating rcuo kthreads for CPUs that never come online. This
+fixes a bug in many instances of firmware: Instead of lying about their
+age, these systems instead lie about the number of CPUs that they have.
+Before commit 35ce7f29a44a, this could result in huge numbers of useless
+rcuo kthreads being created.
+
+It appears that experience indicates that I should have told the
+people suffering from this problem to fix their broken firmware, but
+I instead produced what turned out to be a partial fix. The missing
+piece supplied by this commit makes sure that rcu_barrier() knows not to
+post callbacks for no-CBs CPUs that have not yet come online, because
+otherwise rcu_barrier() will hang on systems having firmware that lies
+about the number of CPUs.
+
+It is tempting to simply have rcu_barrier() refuse to post a callback on
+any no-CBs CPU that does not have an rcuo kthread. This unfortunately
+does not work because rcu_barrier() is required to wait for all pending
+callbacks. It is therefore required to wait even for those callbacks
+that cannot possibly be invoked. Even if doing so hangs the system.
+
+Given that posting a callback to a no-CBs CPU that does not yet have an
+rcuo kthread can hang rcu_barrier(), It is tempting to report an error
+in this case. Unfortunately, this will result in false positives at
+boot time, when it is perfectly legal to post callbacks to the boot CPU
+before the scheduler has started, in other words, before it is legal
+to invoke rcu_barrier().
+
+So this commit instead has rcu_barrier() avoid posting callbacks to
+CPUs having neither rcuo kthread nor pending callbacks, and has it
+complain bitterly if it finds CPUs having no rcuo kthread but some
+pending callbacks. And when rcu_barrier() does find CPUs having no rcuo
+kthread but pending callbacks, as noted earlier, it has no choice but
+to hang indefinitely.
+
+Reported-by: Yanko Kaneti <yaneti@declera.com>
+Reported-by: Jay Vosburgh <jay.vosburgh@canonical.com>
+Reported-by: Meelis Roos <mroos@linux.ee>
+Reported-by: Eric B Munson <emunson@akamai.com>
+Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Tested-by: Eric B Munson <emunson@akamai.com>
+---
+ include/trace/events/rcu.h | 18 +++++++++---------
+ kernel/rcu/tree.c | 15 ++++++++++-----
+ kernel/rcu/tree.h | 1 +
+ kernel/rcu/tree_plugin.h | 33 +++++++++++++++++++++++++++++++++
+ 4 files changed, 53 insertions(+), 14 deletions(-)
+
+diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h
+index 9b56f37148cf..e335e7d8c6c2 100644
+--- a/include/trace/events/rcu.h
++++ b/include/trace/events/rcu.h
+@@ -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.
+ */
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 133e47223095..9815447d22e0 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -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)) {
+- _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);
++ 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);
++ }
+ } else if (ACCESS_ONCE(rdp->qlen)) {
+ _rcu_barrier_trace(rsp, "OnlineQ", cpu,
+ rsp->n_barrier_done);
+diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h
+index d03764652d91..bbdc45d8d74f 100644
+--- a/kernel/rcu/tree.h
++++ b/kernel/rcu/tree.h
+@@ -587,6 +587,7 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu);
+ static void print_cpu_stall_info_end(void);
+ static void zero_cpu_stall_ticks(struct rcu_data *rdp);
+ static void increment_cpu_stall_ticks(void);
++static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu);
+ static void rcu_nocb_gp_set(struct rcu_node *rnp, int nrq);
+ static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp);
+ static void rcu_init_one_nocb(struct rcu_node *rnp);
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
+index 387dd4599344..c1d7f27bd38f 100644
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -2050,6 +2050,33 @@ static void wake_nocb_leader(struct rcu_data *rdp, bool force)
+ }
+
+ /*
++ * Does the specified CPU need an RCU callback for the specified flavor
++ * of rcu_barrier()?
++ */
++static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu)
++{
++ struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu);
++ struct rcu_head *rhp;
++
++ /* No-CBs CPUs might have callbacks on any of three lists. */
++ rhp = ACCESS_ONCE(rdp->nocb_head);
++ if (!rhp)
++ rhp = ACCESS_ONCE(rdp->nocb_gp_head);
++ if (!rhp)
++ rhp = ACCESS_ONCE(rdp->nocb_follower_head);
++
++ /* Having no rcuo kthread but CBs after scheduler starts is bad! */
++ if (!ACCESS_ONCE(rdp->nocb_kthread) && rhp) {
++ /* RCU callback enqueued before CPU first came online??? */
++ pr_err("RCU: Never-onlined no-CBs CPU %d has CB %p\n",
++ cpu, rhp->func);
++ WARN_ON_ONCE(1);
++ }
++
++ return !!rhp;
++}
++
++/*
+ * Enqueue the specified string of rcu_head structures onto the specified
+ * CPU's no-CBs lists. The CPU is specified by rdp, the head of the
+ * string by rhp, and the tail of the string by rhtp. The non-lazy/lazy
+@@ -2642,6 +2669,12 @@ static bool init_nocb_callback_list(struct rcu_data *rdp)
+
+ #else /* #ifdef CONFIG_RCU_NOCB_CPU */
+
++static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu)
++{
++ WARN_ON_ONCE(1); /* Should be dead code. */
++ return false;
++}
++
+ static void rcu_nocb_gp_cleanup(struct rcu_state *rsp, struct rcu_node *rnp)
+ {
+ }
+--
+1.9.3
+
diff --git a/rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch b/rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch
new file mode 100644
index 000000000..77770ff12
--- /dev/null
+++ b/rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch
@@ -0,0 +1,67 @@
+From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Date: Wed, 22 Oct 2014 10:00:05 -0700
+Subject: [PATCH] rcu: More on deadlock between CPU hotplug and expedited grace
+ periods
+
+Commit dd56af42bd82 (rcu: Eliminate deadlock between CPU hotplug and
+expedited grace periods) was incomplete. Although it did eliminate
+deadlocks involving synchronize_sched_expedited()'s acquisition of
+cpu_hotplug.lock via get_online_cpus(), it did nothing about the similar
+deadlock involving acquisition of this same lock via put_online_cpus().
+This deadlock became apparent with testing involving hibernation.
+
+This commit therefore changes put_online_cpus() acquisition of this lock
+to be conditional, and increments a new cpu_hotplug.puts_pending field
+in case of acquisition failure. Then cpu_hotplug_begin() checks for this
+new field being non-zero, and applies any changes to cpu_hotplug.refcount.
+
+Reported-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Tested-by: Jiri Kosina <jkosina@suse.cz>
+Tested-by: Borislav Petkov <bp@suse.de>
+---
+ kernel/cpu.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 356450f09c1f..90a3d017b90c 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -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);
+--
+1.9.3
+
diff --git a/sources b/sources
index 2ae36ec2d..d3a573fce 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,4 @@
fb30d0f29214d75cddd2faa94f73d5cf linux-3.17.tar.xz
159e969cbc27201d8e2fa0f609dc722f perf-man-3.17.tar.gz
cdc96388a5c70f5f385925caab06db12 patch-3.18-rc2.xz
+49299760d7aedcae41033aec7d7b61a0 patch-3.18-rc2-git1.xz