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:
parent
995f274d71
commit
c6207348df
@ -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
|
||||
|
112
config-nodebug
112
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_ATOMIC_SLEEP=y
|
||||
|
||||
# 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_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
|
||||
|
@ -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
|
||||
|
15
kernel.spec
15
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.
|
||||
|
177
rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch
Normal file
177
rcu-Make-rcu_barrier-understand-about-missing-rcuo-k.patch
Normal 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
|
||||
|
67
rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch
Normal file
67
rcu-More-on-deadlock-between-CPU-hotplug-and-expedit.patch
Normal 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
|
||||
|
Loading…
Reference in New Issue
Block a user