RCU changes for v3.8
Subsystems (13)
Linus,
Please pull the latest RCU git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-rcu-for-linus
HEAD: 630e1e0bcddfda9566462d4f9a0d58b31c29d467 Merge branch 'rcu/next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu
The major features of this tree are:
1. A first version of no-callbacks CPUs. This version prohibits offlining CPU 0, but only when enabled via CONFIG_RCU_NOCB_CPU=y. Relaxing this constraint is in progress, but not yet ready for prime time. These commits were posted to LKML at
https://lkml.org/lkml/2012/10/30/724.
2. Changes to SRCU that allows statically initialized srcu_struct structures. These commits were posted to LKML at
https://lkml.org/lkml/2012/10/30/296.
3. Restructuring of RCU's debugfs output. These commits were posted to LKML at https://lkml.org/lkml/2012/10/30/341.
4. Additional CPU-hotplug/RCU improvements, posted to LKML at
https://lkml.org/lkml/2012/10/30/327.
Note that the commit eliminating __stop_machine() was judged to be too-high of risk, so is deferred to 3.9.
5. Changes to RCU's idle interface, most notably a new module parameter that redirects normal grace-period operations to their expedited equivalents. These were posted to LKML at
https://lkml.org/lkml/2012/10/30/739.
6. Additional diagnostics for RCU's CPU stall warning facility, posted to LKML at https://lkml.org/lkml/2012/10/30/315.
The most notable change reduces the
default RCU CPU stall-warning time from 60 seconds to 21 seconds, so that it once again happens sooner than the softlockup timeout.
7. Documentation updates, which were posted to LKML at
https://lkml.org/lkml/2012/10/30/280.
A couple of late-breaking changes were posted at
https://lkml.org/lkml/2012/11/16/634 and
https://lkml.org/lkml/2012/11/16/547.
8. Miscellaneous fixes, which were posted to LKML at
https://lkml.org/lkml/2012/10/30/309.
9. Finally, a fix for an lockdep-RCU splat was posted to LKML at https://lkml.org/lkml/2012/11/7/486.
Thanks,
Ingo
------------------>
Antti P Miettinen (1):
rcu: Add a module parameter to force use of expedited RCU primitives
Dhaval Giani (1):
rcu: Correct the name of a reference in list of RCU papers
Eric Dumazet (1):
rcu: Fix batch-limit size problem
Frederic Weisbecker (2):
rcu: Remove rcu_switch()
context_tracking: New context tracking susbsystem
Kees Cook (1):
rcu: Update docs to include kfree_rcu()
Lai Jiangshan (4):
srcu: Credit Lai Jiangshan with SRCU rewrite
srcu: Export process_srcu()
srcu: Add DEFINE_SRCU()
rcutorture: Use DEFINE_STATIC_SRCU()
Michael Wang (12):
rcu: Create directory for each flavor of rcu
rcu: Fundamental facility for 'CPU units sequence reading'
rcu: Optimize the 'rcudata' for RCU trace
rcu: Optimize the 'rcudata.csv' for RCU trace
rcu: Optimize the 'rcu_pending' for RCU trace
rcu: Replace the old interface with the new one
rcu: Remove the interface "rcudata.csv"
rcu: split 'rcubarrier' to each flavor
rcu: split 'rcuboost' to each flavor
rcu: split 'rcugp' to each flavor
rcu: split 'rcuhier' to each flavor
rcu: Remove old debugfs interfaces and also RCU flavor name
Paul E. McKenney (26):
rcu: Accelerate callbacks for CPU initiating a grace period
Documentation: Fix memory-barriers.txt example
rcu: Fix comment about _rcu_barrier()/orphanage exclusion
rcu: Make rcutorture give diagnostics if CPU offline fails
rcu: Update RCU_FAST_NO_HZ help text
rcu: Fix precedence error in cpu_needs_another_gp()
rcu: Print remote CPU's stacks in stall warnings
rcu: Add grace-period information to RCU CPU stall warnings
rcu: Dump number of callbacks in stall warning messages
rcu: Document alternative RCU/reference-count algorithms
rcu: Rename ->onofflock to ->orphan_lock
rcu: Avoid counter wrap in synchronize_sched_expedited()
rcu: Move synchronize_sched_expedited() state to rcu_state
rcu: Instrument synchronize_rcu_expedited() for debugfs tracing
rcu: Fix tracing formatting
rcu: Add tracing for synchronize_sched_expedited()
rcu: Remove list_for_each_continue_rcu()
rcu: Add new rcutorture module parameters to start/end test messages
rcu: Clarify memory-ordering properties of grace-period primitives
rcu: Fix TINY_RCU rcu_is_cpu_rrupt_from_idle check
rcu: Reduce default RCU CPU stall warning timeout
rcu: Update documentation for TREE_RCU debugfs tracing
rcu: Add documentation for the new rcuexp debugfs trace file
rcu: Add callback-free CPUs
rcu: Separate accounting of callbacks from callback-free CPUs
sched: Mark RCU reader in sched_show_task()
Paul Gortmaker (1):
rcu: Wordsmith help text for RCU_USER_QS kernel parameter
Documentation/RCU/RTFP.txt | 2 +-
Documentation/RCU/checklist.txt | 17 +-
Documentation/RCU/listRCU.txt | 2 +-
Documentation/RCU/rcuref.txt | 61 ++-
Documentation/RCU/trace.txt | 396 +++++++++++---------
Documentation/RCU/whatisRCU.txt | 17 +-
Documentation/kernel-parameters.txt | 21 ++
Documentation/memory-barriers.txt | 9 +-
arch/Kconfig | 15 +-
arch/um/drivers/mconsole_kern.c | 2 +-
arch/x86/Kconfig | 2 +-
arch/x86/include/asm/{rcu.h => context_tracking.h} | 15 +-
arch/x86/kernel/entry_64.S | 2 +-
arch/x86/kernel/ptrace.c | 7 +-
arch/x86/kernel/signal.c | 5 +-
arch/x86/kernel/traps.c | 2 +-
arch/x86/mm/fault.c | 2 +-
include/linux/context_tracking.h | 18 +
include/linux/rculist.h | 17 -
include/linux/rcupdate.h | 29 +-
include/linux/sched.h | 10 +-
include/linux/srcu.h | 34 ++
include/trace/events/rcu.h | 1 +
init/Kconfig | 67 ++--
kernel/Makefile | 1 +
kernel/context_tracking.c | 83 +++++
kernel/ksysfs.c | 18 +
kernel/rcu.h | 2 +
kernel/rcupdate.c | 3 +
kernel/rcutiny.c | 2 +-
kernel/rcutiny_plugin.h | 5 +-
kernel/rcutorture.c | 54 +--
kernel/rcutree.c | 347 ++++++++++-------
kernel/rcutree.h | 67 +++-
kernel/rcutree_plugin.h | 415 ++++++++++++++++++++-
kernel/rcutree_trace.c | 330 ++++++++--------
kernel/sched/core.c | 23 +-
kernel/srcu.c | 16 +-
lib/Kconfig.debug | 2 +-
39 files changed, 1493 insertions(+), 628 deletions(-)
rename arch/x86/include/asm/{rcu.h => context_tracking.h} (63%)
create mode 100644 include/linux/context_tracking.h
create mode 100644 kernel/context_tracking.cDocumentation/RCU/RTFP.txt +1 -1
@@ -186,7 +186,7 @@ Bibtex Entries @article{Kung80 ,author="H. T. Kung and Q. Lehman" -,title="Concurrent Maintenance of Binary Search Trees" +,title="Concurrent Manipulation of Binary Search Trees" ,Year="1980" ,Month="September" ,journal="ACM Transactions on Database Systems"
Documentation/RCU/checklist.txt +8 -9
@@ -271,15 +271,14 @@ over a rather long period of time, but improvements are always welcome! The same cautions apply to call_rcu_bh() and call_rcu_sched(). 9. All RCU list-traversal primitives, which include - rcu_dereference(), list_for_each_entry_rcu(), - list_for_each_continue_rcu(), and list_for_each_safe_rcu(), - must be either within an RCU read-side critical section or - must be protected by appropriate update-side locks. RCU - read-side critical sections are delimited by rcu_read_lock() - and rcu_read_unlock(), or by similar primitives such as - rcu_read_lock_bh() and rcu_read_unlock_bh(), in which case - the matching rcu_dereference() primitive must be used in order - to keep lockdep happy, in this case, rcu_dereference_bh(). + rcu_dereference(), list_for_each_entry_rcu(), and + list_for_each_safe_rcu(), must be either within an RCU read-side + critical section or must be protected by appropriate update-side + locks. RCU read-side critical sections are delimited by + rcu_read_lock() and rcu_read_unlock(), or by similar primitives + such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which + case the matching rcu_dereference() primitive must be used in + order to keep lockdep happy, in this case, rcu_dereference_bh(). The reason that it is permissible to use RCU list-traversal primitives when the update-side lock is held is that doing so
Documentation/RCU/listRCU.txt +1 -1
@@ -205,7 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows: audit_copy_rule(&ne->rule, &e->rule); ne->rule.action = newaction; ne->rule.file_count = newfield_count; - list_replace_rcu(e, ne); + list_replace_rcu(&e->list, &ne->list); call_rcu(&e->rcu, audit_free_rule); return 0; }
Documentation/RCU/rcuref.txt +59 -2
76 lines not on this page · raw message
Documentation/RCU/trace.txt +218 -178
525 lines not on this page · raw message
Documentation/RCU/whatisRCU.txt +12 -5
@@ -499,6 +499,8 @@ The foo_reclaim() function might appear as follows: { struct foo *fp = container_of(rp, struct foo, rcu); + foo_cleanup(fp->a); + kfree(fp); }
@@ -521,6 +523,12 @@ o Use call_rcu() -after- removing a data element from an read-side critical sections that might be referencing that data item. +If the callback for call_rcu() is not doing anything more than calling +kfree() on the structure, you can use kfree_rcu() instead of call_rcu() +to avoid having to write your own callback: + + kfree_rcu(old_fp, rcu); + Again, see checklist.txt for additional rules governing the use of RCU.
@@ -773,8 +781,8 @@ a single atomic update, converting to RCU will require special care. Also, the presence of synchronize_rcu() means that the RCU version of delete() can now block. If this is a problem, there is a callback-based -mechanism that never blocks, namely call_rcu(), that can be used in -place of synchronize_rcu(). +mechanism that never blocks, namely call_rcu() or kfree_rcu(), that can +be used in place of synchronize_rcu(). 7. FULL LIST OF RCU APIs
@@ -789,9 +797,7 @@ RCU list traversal: list_for_each_entry_rcu hlist_for_each_entry_rcu hlist_nulls_for_each_entry_rcu - - list_for_each_continue_rcu (to be deprecated in favor of new - list_for_each_entry_continue_rcu) + list_for_each_entry_continue_rcu RCU pointer/list update:
@@ -813,6 +819,7 @@ RCU: Critical sections Grace period Barrier rcu_read_unlock synchronize_rcu rcu_dereference synchronize_rcu_expedited call_rcu + kfree_rcu bh: Critical sections Grace period Barrier
Documentation/kernel-parameters.txt +21 -0
@@ -2394,6 +2394,27 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ramdisk_size= [RAM] Sizes of RAM disks in kilobytes See Documentation/blockdev/ramdisk.txt. + rcu_nocbs= [KNL,BOOT] + In kernels built with CONFIG_RCU_NOCB_CPU=y, set + the specified list of CPUs to be no-callback CPUs. + Invocation of these CPUs' RCU callbacks will + be offloaded to "rcuoN" kthreads created for + that purpose. This reduces OS jitter on the + offloaded CPUs, which can be useful for HPC and + real-time workloads. It can also improve energy + efficiency for asymmetric multiprocessors. + + rcu_nocbs_poll [KNL,BOOT] + Rather than requiring that offloaded CPUs + (specified by rcu_nocbs= above) explicitly + awaken the corresponding "rcuoN" kthreads, + make these kthreads poll for callbacks. + This improves the real-time response for the + offloaded CPUs by relieving them of the need to + wake up the corresponding kthread, but degrades + energy efficiency by requiring that the kthreads + periodically wake up to do the polling. + rcutree.blimit= [KNL,BOOT] Set maximum number of finished RCU callbacks to process in one batch.
Documentation/memory-barriers.txt +5 -4
@@ -251,12 +251,13 @@ And there are a number of things that _must_ or _must_not_ be assumed: And for: - *A = X; Y = *A; + *A = X; *(A + 4) = Y; - we may get either of: + we may get any of: - STORE *A = X; Y = LOAD *A; - STORE *A = Y = X; + STORE *A = X; STORE *(A + 4) = Y; + STORE *(A + 4) = Y; STORE *A = X; + STORE {*A, *(A + 4) } = {X, Y}; =========================
arch/Kconfig +8 -7
@@ -300,15 +300,16 @@ config SECCOMP_FILTER See Documentation/prctl/seccomp_filter.txt for details. -config HAVE_RCU_USER_QS +config HAVE_CONTEXT_TRACKING bool help - Provide kernel entry/exit hooks necessary for userspace - RCU extended quiescent state. Syscalls need to be wrapped inside - rcu_user_exit()-rcu_user_enter() through the slow path using - TIF_NOHZ flag. Exceptions handlers must be wrapped as well. Irqs - are already protected inside rcu_irq_enter/rcu_irq_exit() but - preemption or signal handling on irq exit still need to be protected. + Provide kernel/user boundaries probes necessary for subsystems + that need it, such as userspace RCU extended quiescent state. + Syscalls need to be wrapped inside user_exit()-user_enter() through + the slow path using TIF_NOHZ flag. Exceptions handlers must be + wrapped as well. Irqs are already protected inside + rcu_irq_enter/rcu_irq_exit() but preemption or signal handling on + irq exit still need to be protected. config HAVE_VIRT_CPU_ACCOUNTING bool
arch/um/drivers/mconsole_kern.c +1 -1
@@ -648,7 +648,7 @@ static void stack_proc(void *arg)struct task_struct *from = current, *to = arg; to->thread.saved_task = from; -rcu_switch (from, to); +rcu_user_hooks_switch (from, to);switch_to (from, to, from); }
arch/x86/Kconfig +1 -1
@@ -106,7 +106,7 @@ config X86 select KTIME_SCALAR if X86_32 select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNLEN_USER - select HAVE_RCU_USER_QS if X86_64 + select HAVE_CONTEXT_TRACKING if X86_64 select HAVE_IRQ_TIME_ACCOUNTING select GENERIC_KERNEL_THREAD select GENERIC_KERNEL_EXECVE
arch/x86/include/asm/context_tracking.h renamed from arch/x86/include/asm/rcu.h +7 -8
@@ -1,27 +1,26 @@ -#ifndef _ASM_X86_RCU_H -#define _ASM_X86_RCU_H +#ifndef _ASM_X86_CONTEXT_TRACKING_H +#define _ASM_X86_CONTEXT_TRACKING_H#ifndef __ASSEMBLY__ - -#include <linux/rcupdate.h> +#include <linux/context_tracking.h> #include <asm/ptrace.h> static inline void exception_enter (struct pt_regs *regs) { -rcu_user_exit (); +user_exit (); }static inline void exception_exit (struct pt_regs *regs) { -#ifdef CONFIG_RCU_USER_QS +#ifdef CONFIG_CONTEXT_TRACKING if (user_mode (regs)) -rcu_user_enter (); +user_enter ();#endif }#else /* __ASSEMBLY__ */ -#ifdef CONFIG_RCU_USER_QS +#ifdef CONFIG_CONTEXT_TRACKING # define SCHEDULE_USER call schedule_user#else # define SCHEDULE_USER call schedule
arch/x86/kernel/entry_64.S +1 -1
@@ -56,7 +56,7 @@ #include <asm/ftrace.h> #include <asm/percpu.h> #include <asm/asm.h> -#include <asm/rcu.h> +#include <asm/context_tracking.h> #include <asm/smap.h> #include <linux/err.h>
arch/x86/kernel/ptrace.c +4 -3
@@ -23,6 +23,7 @@#include <linux/hw_breakpoint.h> #include <linux/rcupdate.h> #include <linux/module.h> +#include <linux/context_tracking.h> #include <asm/uaccess.h> #include <asm/pgtable.h>
@@ -1491,7 +1492,7 @@ long syscall_trace_enter(struct pt_regs *regs) {long ret =0 ; -rcu_user_exit (); +user_exit ();/* * If we stepped into a sysenter/syscall insn, it trapped in
@@ -1546,7 +1547,7 @@ void syscall_trace_leave(struct pt_regs *regs)* or do_notify_resume(), in which case we can be in RCU * user mode. */ -rcu_user_exit (); +user_exit ();audit_syscall_exit (regs);
@@ -1564,5 +1565,5 @@ void syscall_trace_leave(struct pt_regs *regs)if (step ||test_thread_flag (TIF_SYSCALL_TRACE ))tracehook_report_syscall_exit (regs, step); -rcu_user_enter (); +user_enter (); }
arch/x86/kernel/signal.c +3 -2
@@ -22,6 +22,7 @@#include <linux/uaccess.h> #include <linux/user-return-notifier.h> #include <linux/uprobes.h> +#include <linux/context_tracking.h> #include <asm/processor.h> #include <asm/ucontext.h>
@@ -816,7 +817,7 @@ static void do_signal(struct pt_regs *regs)void do_notify_resume (struct pt_regs *regs,void *unused,__u32 thread_info_flags) { -rcu_user_exit (); +user_exit ();#ifdef CONFIG_X86_MCE /* notify userspace of pending MCEs */
@@ -838,7 +839,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)fire_user_return_notifiers (); -rcu_user_enter (); +user_enter (); }void signal_fault (struct pt_regs *regs,void __user *frame,char *where)
arch/x86/kernel/traps.c +1 -1
@@ -55,7 +55,7 @@#include <asm/i387.h> #include <asm/fpu-internal.h> #include <asm/mce.h> -#include <asm/rcu.h> +#include <asm/context_tracking.h> #include <asm/mach_traps.h>
arch/x86/mm/fault.c +1 -1
@@ -18,7 +18,7 @@#include <asm/pgalloc.h> /* pgd_*(), ... */ #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ #include <asm/fixmap.h> /* VSYSCALL_START */ -#include <asm/rcu.h> /* exception_enter(), ... */ +#include <asm/context_tracking.h> /* exception_enter(), ... */ /* * Page fault error code bits:
include/linux/context_tracking.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef _LINUX_CONTEXT_TRACKING_H +#define _LINUX_CONTEXT_TRACKING_H + +#ifdef CONFIG_CONTEXT_TRACKING +#include <linux/sched.h> + +extern void user_enter (void ); +extern void user_exit (void ); +extern void context_tracking_task_switch (struct task_struct *prev, +struct task_struct *next); +#else +static inline void user_enter (void ) { } +static inline void user_exit (void ) { } +static inline void context_tracking_task_switch (struct task_struct *prev, +struct task_struct *next) { } +#endif /* !CONFIG_CONTEXT_TRACKING */ + +#endif
include/linux/rculist.h +0 -17
@@ -286,23 +286,6 @@ static inline void list_splice_init_rcu(struct list_head *list, &pos->member != (head); \ pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) - -/** -* list_for_each_continue_rcu -* @pos: the &struct list_head to use as a loop cursor. -* @head: the head for your list. -* -* Iterate over an rcu-protected list, continuing after current point. -* -* This list-traversal primitive may safely run concurrently with -* the _rcu list-mutation primitives such as list_add_rcu() -* as long as the traversal is guarded by rcu_read_lock(). -*/ -#define list_for_each_continue_rcu (pos, head) \ - for ((pos) = rcu_dereference_raw(list_next_rcu(pos)); \ - (pos) != (head); \ - (pos) = rcu_dereference_raw(list_next_rcu(pos))) -/** * list_for_each_entry_continue_rcu - continue iteration over list of given type * @pos: the type * to use as a loop cursor.
include/linux/rcupdate.h +27 -2
@@ -90,6 +90,25 @@ extern void do_trace_rcu_torture_read(char *rcutorturename,* that started after call_rcu() was invoked. RCU read-side critical * sections are delimited by rcu_read_lock() and rcu_read_unlock(), * and may be nested. +* +* Note that all CPUs must agree that the grace period extended beyond +* all pre-existing RCU read-side critical section. On systems with more +* than one CPU, this means that when "func()" is invoked, each CPU is +* guaranteed to have executed a full memory barrier since the end of its +* last RCU read-side critical section whose beginning preceded the call +* to call_rcu(). It also means that each CPU executing an RCU read-side +* critical section that continues beyond the start of "func()" must have +* executed a memory barrier after the call_rcu() but before the beginning +* of that RCU read-side critical section. Note that these guarantees +* include CPUs that are offline, idle, or executing in user mode, as +* well as CPUs that are executing in the kernel. +* +* Furthermore, if CPU A invoked call_rcu() and CPU B invoked the +* resulting RCU callback function "func()", then both CPU A and CPU B are +* guaranteed to execute a full memory barrier during the time interval +* between the call to call_rcu() and the invocation of "func()" -- even +* if CPU A and CPU B are the same CPU (but again only if the system has +* more than one CPU). */ extern void call_rcu (struct rcu_head *head,void (*func)(struct rcu_head *head));
@@ -118,6 +137,9 @@ extern void call_rcu(struct rcu_head *head,* OR * - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context. * These may be nested. +* +* See the description of call_rcu() for more detailed information on +* memory ordering guarantees. */ extern void call_rcu_bh (struct rcu_head *head,void (*func)(struct rcu_head *head));
@@ -137,6 +159,9 @@ extern void call_rcu_bh(struct rcu_head *head,* OR * anything that disables preemption. * These may be nested. +* +* See the description of call_rcu() for more detailed information on +* memory ordering guarantees. */ extern void call_rcu_sched (struct rcu_head *head,void (*func)(struct rcu_head *rcu));
@@ -197,13 +222,13 @@ extern void rcu_user_enter(void);extern void rcu_user_exit (void );extern void rcu_user_enter_after_irq (void );extern void rcu_user_exit_after_irq (void ); -extern void rcu_user_hooks_switch (struct task_struct *prev, -struct task_struct *next);#else static inline void rcu_user_enter (void ) { }static inline void rcu_user_exit (void ) { }static inline void rcu_user_enter_after_irq (void ) { }static inline void rcu_user_exit_after_irq (void ) { } +static inline void rcu_user_hooks_switch (struct task_struct *prev, +struct task_struct *next) { }#endif /* CONFIG_RCU_USER_QS */ extern void exit_rcu (void );
include/linux/sched.h +2 -8
@@ -109,6 +109,8 @@ extern void update_cpu_load_nohz(void);extern unsigned long get_parent_ip (unsigned long addr); +extern void dump_cpu_task (int cpu); +struct seq_file ;struct cfs_rq ;struct task_group ;
@@ -1844,14 +1846,6 @@ static inline void rcu_copy_process(struct task_struct *p)#endif -static inline void rcu_switch (struct task_struct *prev, -struct task_struct *next) -{ -#ifdef CONFIG_RCU_USER_QS -rcu_user_hooks_switch (prev, next); -#endif -} -static inline void tsk_restore_flags (struct task_struct *task,unsigned long orig_flags,unsigned long flags) {
include/linux/srcu.h +34 -0
@@ -16,8 +16,10 @@* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) IBM Corporation, 2006 +* Copyright (C) Fujitsu, 2012 * * Author: Paul McKenney <[email protected]> +* Lai Jiangshan <[email protected]> * * For detailed explanation of Read-Copy Update mechanism see - * Documentation/RCU/ *.txt
@@ -40,6 +42,8 @@ struct rcu_batch {struct rcu_head *head, **tail; }; +#define RCU_BATCH_INIT (name) { NULL, &(name.head) } +struct srcu_struct {unsigned completed;struct srcu_struct_array __percpu *per_cpu_ref;
@@ -70,12 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name, __init_srcu_struct((sp), #sp, &__srcu_key); \ }) +#define __SRCU_DEP_MAP_INIT (srcu_name) .dep_map = { .name = #srcu_name },#else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ int init_srcu_struct (struct srcu_struct *sp); +#define __SRCU_DEP_MAP_INIT (srcu_name)#endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +void process_srcu (struct work_struct *work); + +#define __SRCU_STRUCT_INIT (name) \ + { \ + .completed = -300, \ + .per_cpu_ref = &name##_srcu_array, \ + .queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \ + .running = false, \ + .batch_queue = RCU_BATCH_INIT(name.batch_queue), \ + .batch_check0 = RCU_BATCH_INIT(name.batch_check0), \ + .batch_check1 = RCU_BATCH_INIT(name.batch_check1), \ + .batch_done = RCU_BATCH_INIT(name.batch_done), \ + .work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu, 0),\ + __SRCU_DEP_MAP_INIT(name) \ + } + +/* +* define and init a srcu struct at build time. +* dont't call init_srcu_struct() nor cleanup_srcu_struct() on it. +*/ +#define DEFINE_SRCU (name) \ + static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ + struct srcu_struct name = __SRCU_STRUCT_INIT(name); + +#define DEFINE_STATIC_SRCU (name) \ + static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ + static struct srcu_struct name = __SRCU_STRUCT_INIT(name); +/** * call_srcu() - Queue a callback for invocation after an SRCU grace period * @sp: srcu_struct in queue the callback
include/trace/events/rcu.h +1 -0
@@ -549,6 +549,7 @@ TRACE_EVENT(rcu_torture_read,* "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. * "IRQ": An rcu_barrier_callback() callback posted on remote CPU.
init/Kconfig +44 -23
99 lines not on this page · raw message
kernel/Makefile +1 -0
@@ -110,6 +110,7 @@ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o obj-$(CONFIG_PADATA) += padata.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o +obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o $(obj)/configs.o: $(obj)/config_data.h
kernel/context_tracking.c new file +83 -0
83 lines not on this page · raw message
kernel/ksysfs.c +18 -0
@@ -141,6 +141,23 @@ static ssize_t fscaps_show(struct kobject *kobj, }KERNEL_ATTR_RO (fscaps); +int rcu_expedited; +static ssize_t rcu_expedited_show (struct kobject *kobj, +struct kobj_attribute *attr,char *buf) +{ +return sprintf (buf,"%d\n" , rcu_expedited); +} +static ssize_t rcu_expedited_store (struct kobject *kobj, +struct kobj_attribute *attr, +const char *buf,size_t count) +{ +if (kstrtoint (buf,0 , &rcu_expedited)) +return -EINVAL ; + +return count; +} +KERNEL_ATTR_RW (rcu_expedited); +/* * Make /sys/kernel/notes give the raw contents of our kernel .notes section. */
@@ -182,6 +199,7 @@ static struct attribute * kernel_attrs[] = { &kexec_crash_size_attr.attr, &vmcoreinfo_attr.attr, #endif + &rcu_expedited_attr.attr,NULL };
kernel/rcu.h +2 -0
@@ -109,4 +109,6 @@ static inline bool __rcu_reclaim(char *rn, struct rcu_head *head) } } +extern int rcu_expedited; +#endif /* __LINUX_RCU_H */
kernel/rcupdate.c +3 -0
@@ -46,12 +46,15 @@#include <linux/export.h> #include <linux/hardirq.h> #include <linux/delay.h> +#include <linux/module.h> #define CREATE_TRACE_POINTS #include <trace/events/rcu.h> #include "rcu.h" +module_param (rcu_expedited, int,0 ); +#ifdef CONFIG_PREEMPT_RCU /*
kernel/rcutiny.c +1 -1
@@ -195,7 +195,7 @@ EXPORT_SYMBOL(rcu_is_cpu_idle);*/ int rcu_is_cpu_rrupt_from_idle (void ) { -return rcu_dynticks_nesting <=0 ; +return rcu_dynticks_nesting <=1 ; }/*
kernel/rcutiny_plugin.h +4 -1
@@ -706,7 +706,10 @@ void synchronize_rcu(void)return ;/* Once we get past the fastpath checks, same code as rcu_barrier(). */ -rcu_barrier (); +if (rcu_expedited) +synchronize_rcu_expedited (); +else +rcu_barrier (); }EXPORT_SYMBOL_GPL (synchronize_rcu);
kernel/rcutorture.c +18 -36
180 lines not on this page · raw message
kernel/rcutree.c +222 -125
627 lines not on this page · raw message
kernel/rcutree.h +63 -4
114 lines not on this page · raw message
kernel/rcutree_plugin.h +409 -6
484 lines not on this page · raw message
kernel/rcutree_trace.c +162 -168
268 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.