Linux v3.18-rc2-43-gf7e87a44ef60

- Add two RCU patches to fix a deadlock and a hang
- Reenable debugging options.
This commit is contained in:
Josh Boyer 2014-10-28 09:55:15 -04:00
parent 995f274d71
commit c6207348df
7 changed files with 318 additions and 62 deletions

View File

@ -1699,13 +1699,13 @@ CONFIG_B43_PCMCIA=y
CONFIG_B43_SDIO=y CONFIG_B43_SDIO=y
CONFIG_B43_BCMA=y CONFIG_B43_BCMA=y
CONFIG_B43_BCMA_PIO=y CONFIG_B43_BCMA_PIO=y
# CONFIG_B43_DEBUG is not set CONFIG_B43_DEBUG=y
CONFIG_B43_PHY_LP=y CONFIG_B43_PHY_LP=y
CONFIG_B43_PHY_N=y CONFIG_B43_PHY_N=y
CONFIG_B43_PHY_HT=y CONFIG_B43_PHY_HT=y
CONFIG_B43_PHY_G=y CONFIG_B43_PHY_G=y
CONFIG_B43LEGACY=m CONFIG_B43LEGACY=m
# CONFIG_B43LEGACY_DEBUG is not set CONFIG_B43LEGACY_DEBUG=y
CONFIG_B43LEGACY_DMA=y CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=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_DPM_WATCHDOG is not set # revisit this in debug
CONFIG_PM_TRACE=y CONFIG_PM_TRACE=y
CONFIG_PM_TRACE_RTC=y CONFIG_PM_TRACE_RTC=y
# CONFIG_PM_TEST_SUSPEND is not set CONFIG_PM_TEST_SUSPEND=y
CONFIG_PM_RUNTIME=y CONFIG_PM_RUNTIME=y
# CONFIG_PM_OPP is not set # CONFIG_PM_OPP is not set
# CONFIG_PM_AUTOSLEEP is not set # CONFIG_PM_AUTOSLEEP is not set

View File

@ -2,115 +2,115 @@ CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y CONFIG_SND_DEBUG=y
CONFIG_SND_PCM_XRUN_DEBUG=y CONFIG_SND_PCM_XRUN_DEBUG=y
# CONFIG_DEBUG_ATOMIC_SLEEP is not set CONFIG_DEBUG_ATOMIC_SLEEP=y
# CONFIG_DEBUG_MUTEXES is not set CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_RT_MUTEXES is not set CONFIG_DEBUG_RT_MUTEXES=y
# CONFIG_DEBUG_LOCK_ALLOC is not set CONFIG_DEBUG_LOCK_ALLOC=y
# CONFIG_LOCK_TORTURE_TEST is not set CONFIG_LOCK_TORTURE_TEST=m
# CONFIG_PROVE_LOCKING is not set CONFIG_PROVE_LOCKING=y
# CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_SPINLOCK=y
# CONFIG_PROVE_RCU is not set CONFIG_PROVE_RCU=y
# CONFIG_PROVE_RCU_REPEATEDLY is not set # 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_CPUMASK_OFFSTACK=y
# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
# CONFIG_FAULT_INJECTION is not set CONFIG_FAULT_INJECTION=y
# CONFIG_FAILSLAB is not set CONFIG_FAILSLAB=y
# CONFIG_FAIL_PAGE_ALLOC is not set CONFIG_FAIL_PAGE_ALLOC=y
# CONFIG_FAIL_MAKE_REQUEST is not set CONFIG_FAIL_MAKE_REQUEST=y
# CONFIG_FAULT_INJECTION_DEBUG_FS is not set CONFIG_FAULT_INJECTION_DEBUG_FS=y
# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
# CONFIG_FAIL_IO_TIMEOUT is not set CONFIG_FAIL_IO_TIMEOUT=y
# CONFIG_FAIL_MMC_REQUEST is not set 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_SG=y
# CONFIG_DEBUG_PI_LIST is not set CONFIG_DEBUG_PI_LIST=y
# CONFIG_DEBUG_PAGEALLOC is not set # 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_SELFTEST is not set
# CONFIG_DEBUG_OBJECTS_FREE is not set CONFIG_DEBUG_OBJECTS_FREE=y
# CONFIG_DEBUG_OBJECTS_TIMERS is not set CONFIG_DEBUG_OBJECTS_TIMERS=y
# CONFIG_DEBUG_OBJECTS_RCU_HEAD is not set CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
# CONFIG_X86_PTDUMP is not set CONFIG_X86_PTDUMP=y
# CONFIG_EFI_PGT_DUMP is not set 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, # off in both production debug and nodebug builds,
# on in rawhide 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_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_ATH_DEBUG=y
# CONFIG_CARL9170_DEBUGFS is not set CONFIG_CARL9170_DEBUGFS=y
# CONFIG_IWLWIFI_DEVICE_TRACING is not set CONFIG_IWLWIFI_DEVICE_TRACING=y
# CONFIG_RTLWIFI_DEBUG is not set # 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_DEBUG=y
# CONFIG_DMADEVICES_VDEBUG is not set CONFIG_DMADEVICES_VDEBUG=y
CONFIG_PM_ADVANCED_DEBUG=y CONFIG_PM_ADVANCED_DEBUG=y
# CONFIG_CEPH_LIB_PRETTYDEBUG is not set CONFIG_CEPH_LIB_PRETTYDEBUG=y
# CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_DEBUG=y
CONFIG_KGDB_KDB=y CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y CONFIG_KDB_KEYBOARD=y
CONFIG_KDB_CONTINUE_CATASTROPHIC=0 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_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_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_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set # 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_EARLY_LOG_SIZE=1024
# CONFIG_DEBUG_KMEMLEAK_TEST is not set # CONFIG_DEBUG_KMEMLEAK_TEST is not set
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
@ -121,7 +121,7 @@ CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
# CONFIG_SPI_DEBUG is not set # 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_SCHEDSTATS is not set
# CONFIG_LATENCYTOP is not set # CONFIG_LATENCYTOP is not set

View File

@ -337,7 +337,7 @@ CONFIG_SP5100_TCO=m
# CONFIG_MEMTEST is not set # CONFIG_MEMTEST is not set
# CONFIG_DEBUG_TLBFLUSH is not set # CONFIG_DEBUG_TLBFLUSH is not set
# CONFIG_MAXSMP is not set CONFIG_MAXSMP=y
CONFIG_HP_ILO=m CONFIG_HP_ILO=m

View File

@ -69,7 +69,7 @@ Summary: The Linux kernel
# The rc snapshot level # The rc snapshot level
%define rcrev 2 %define rcrev 2
# The git snapshot level # The git snapshot level
%define gitrev 0 %define gitrev 1
# Set rpm version accordingly # Set rpm version accordingly
%define rpmversion 3.%{upstream_sublevel}.0 %define rpmversion 3.%{upstream_sublevel}.0
%endif %endif
@ -124,7 +124,7 @@ Summary: The Linux kernel
# Set debugbuildsenabled to 1 for production (build separate debug kernels) # Set debugbuildsenabled to 1 for production (build separate debug kernels)
# and 0 for rawhide (all kernels are debug kernels). # and 0 for rawhide (all kernels are debug kernels).
# See also 'make debug' and 'make release'. # 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? # Want to build a vanilla kernel build without any non-upstream patches?
%define with_vanilla %{?_with_vanilla: 1} %{?!_with_vanilla: 0} %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 #rhbz 1111138
Patch26059: i8042-Add-notimeout-quirk-for-Fujitsu-Lifebook-A544-.patch 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 # git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel
Patch30000: kernel-arm64.patch Patch30000: kernel-arm64.patch
@ -1349,6 +1352,9 @@ ApplyPatch asus-nb-wmi-Add-wapf4-quirk-for-the-X550VB.patch
#rhbz 1111138 #rhbz 1111138
ApplyPatch i8042-Add-notimeout-quirk-for-Fujitsu-Lifebook-A544-.patch 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} %if 0%{?aarch64patches}
ApplyPatch kernel-arm64.patch ApplyPatch kernel-arm64.patch
%ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does. %ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does.
@ -2217,6 +2223,11 @@ fi
# ||----w | # ||----w |
# || || # || ||
%changelog %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 * Mon Oct 27 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.18.0-0.rc2.git0.1
- Linux v3.18-rc2 - Linux v3.18-rc2
- Disable debugging options. - Disable debugging options.

View File

@ -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

View File

@ -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

View File

@ -1,3 +1,4 @@
fb30d0f29214d75cddd2faa94f73d5cf linux-3.17.tar.xz fb30d0f29214d75cddd2faa94f73d5cf linux-3.17.tar.xz
159e969cbc27201d8e2fa0f609dc722f perf-man-3.17.tar.gz 159e969cbc27201d8e2fa0f609dc722f perf-man-3.17.tar.gz
cdc96388a5c70f5f385925caab06db12 patch-3.18-rc2.xz cdc96388a5c70f5f385925caab06db12 patch-3.18-rc2.xz
49299760d7aedcae41033aec7d7b61a0 patch-3.18-rc2-git1.xz