Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40393f52 authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

Merge branches 'doctorture.2013.01.29a', 'fixes.2013.01.26a',...

Merge branches 'doctorture.2013.01.29a', 'fixes.2013.01.26a', 'tagcb.2013.01.24a' and 'tiny.2013.01.29b' into HEAD

doctorture.2013.01.11a: Changes to rcutorture and to RCU documentation.

fixes.2013.01.26a: Miscellaneous fixes.

tagcb.2013.01.24a: Tag RCU callbacks with grace-period number to
	simplify callback advancement.

tiny.2013.01.29b: Enhancements to uniprocessor handling in tiny RCU.
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -756,7 +756,7 @@ static inline void rcu_preempt_sleep_check(void)
 * preemptible RCU implementations (TREE_PREEMPT_RCU and TINY_PREEMPT_RCU)
 * in CONFIG_PREEMPT kernel builds, RCU read-side critical sections may
 * be preempted, but explicit blocking is illegal.  Finally, in preemptible
 * RCU implementations in real-time (CONFIG_PREEMPT_RT) kernel builds,
 * RCU implementations in real-time (with -rt patchset) kernel builds,
 * RCU read-side critical sections may be preempted and they may also
 * block, but only when acquiring spinlocks that are subject to priority
 * inheritance.
+7 −5
Original line number Diff line number Diff line
@@ -44,8 +44,10 @@ TRACE_EVENT(rcu_utilization,
 * of a new grace period or the end of an old grace period ("cpustart"
 * and "cpuend", respectively), a CPU passing through a quiescent
 * state ("cpuqs"), a CPU coming online or going offline ("cpuonl"
 * and "cpuofl", respectively), and a CPU being kicked for being too
 * long in dyntick-idle mode ("kick").
 * and "cpuofl", respectively), a CPU being kicked for being too
 * long in dyntick-idle mode ("kick"), a CPU accelerating its new
 * callbacks to RCU_NEXT_READY_TAIL ("AccReadyCB"), and a CPU
 * accelerating its new callbacks to RCU_WAIT_TAIL ("AccWaitCB").
 */
TRACE_EVENT(rcu_grace_period,

@@ -393,7 +395,7 @@ TRACE_EVENT(rcu_kfree_callback,
 */
TRACE_EVENT(rcu_batch_start,

	TP_PROTO(char *rcuname, long qlen_lazy, long qlen, int blimit),
	TP_PROTO(char *rcuname, long qlen_lazy, long qlen, long blimit),

	TP_ARGS(rcuname, qlen_lazy, qlen, blimit),

@@ -401,7 +403,7 @@ TRACE_EVENT(rcu_batch_start,
		__field(char *, rcuname)
		__field(long, qlen_lazy)
		__field(long, qlen)
		__field(int, blimit)
		__field(long, blimit)
	),

	TP_fast_assign(
@@ -411,7 +413,7 @@ TRACE_EVENT(rcu_batch_start,
		__entry->blimit = blimit;
	),

	TP_printk("%s CBs=%ld/%ld bl=%d",
	TP_printk("%s CBs=%ld/%ld bl=%ld",
		  __entry->rcuname, __entry->qlen_lazy, __entry->qlen,
		  __entry->blimit)
);
+11 −1
Original line number Diff line number Diff line
@@ -453,7 +453,7 @@ config TREE_RCU

config TREE_PREEMPT_RCU
	bool "Preemptible tree-based hierarchical RCU"
	depends on PREEMPT && SMP
	depends on PREEMPT
	help
	  This option selects the RCU implementation that is
	  designed for very large SMP systems with hundreds or
@@ -461,6 +461,8 @@ config TREE_PREEMPT_RCU
	  is also required.  It also scales down nicely to
	  smaller systems.

	  Select this option if you are unsure.

config TINY_RCU
	bool "UP-only small-memory-footprint RCU"
	depends on !PREEMPT && !SMP
@@ -486,6 +488,14 @@ config PREEMPT_RCU
	  This option enables preemptible-RCU code that is common between
	  the TREE_PREEMPT_RCU and TINY_PREEMPT_RCU implementations.

config RCU_STALL_COMMON
	def_bool ( TREE_RCU || TREE_PREEMPT_RCU || RCU_TRACE )
	help
	  This option enables RCU CPU stall code that is common between
	  the TINY and TREE variants of RCU.  The purpose is to allow
	  the tiny variants to disable RCU CPU stall warnings, while
	  making these warnings mandatory for the tree variants.

config CONTEXT_TRACKING
       bool

+65 −10
Original line number Diff line number Diff line
/*
 * Context tracking: Probe on high level context boundaries such as kernel
 * and userspace. This includes syscalls and exceptions entry/exit.
 *
 * This is used by RCU to remove its dependency on the timer tick while a CPU
 * runs in userspace.
 *
 *  Started by Frederic Weisbecker:
 *
 * Copyright (C) 2012 Red Hat, Inc., Frederic Weisbecker <fweisbec@redhat.com>
 *
 * Many thanks to Gilad Ben-Yossef, Paul McKenney, Ingo Molnar, Andrew Morton,
 * Steven Rostedt, Peter Zijlstra for suggestions and improvements.
 *
 */

#include <linux/context_tracking.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
@@ -6,8 +22,8 @@

struct context_tracking {
	/*
	 * When active is false, hooks are not set to
	 * minimize overhead: TIF flags are cleared
	 * When active is false, probes are unset in order
	 * to minimize overhead: TIF flags are cleared
	 * and calls to user_enter/exit are ignored. This
	 * may be further optimized using static keys.
	 */
@@ -24,6 +40,15 @@ static DEFINE_PER_CPU(struct context_tracking, context_tracking) = {
#endif
};

/**
 * user_enter - Inform the context tracking that the CPU is going to
 *              enter userspace mode.
 *
 * This function must be called right before we switch from the kernel
 * to userspace, when it's guaranteed the remaining kernel instructions
 * to execute won't use any RCU read side critical section because this
 * function sets RCU in extended quiescent state.
 */
void user_enter(void)
{
	unsigned long flags;
@@ -39,40 +64,70 @@ void user_enter(void)
	if (in_interrupt())
		return;

	/* Kernel threads aren't supposed to go to userspace */
	WARN_ON_ONCE(!current->mm);

	local_irq_save(flags);
	if (__this_cpu_read(context_tracking.active) &&
	    __this_cpu_read(context_tracking.state) != IN_USER) {
		__this_cpu_write(context_tracking.state, IN_USER);
		/*
		 * At this stage, only low level arch entry code remains and
		 * then we'll run in userspace. We can assume there won't be
		 * any RCU read-side critical section until the next call to
		 * user_exit() or rcu_irq_enter(). Let's remove RCU's dependency
		 * on the tick.
		 */
		rcu_user_enter();
	}
	local_irq_restore(flags);
}


/**
 * user_exit - Inform the context tracking that the CPU is
 *             exiting userspace mode and entering the kernel.
 *
 * This function must be called after we entered the kernel from userspace
 * before any use of RCU read side critical section. This potentially include
 * any high level kernel code like syscalls, exceptions, signal handling, etc...
 *
 * This call supports re-entrancy. This way it can be called from any exception
 * handler without needing to know if we came from userspace or not.
 */
void user_exit(void)
{
	unsigned long flags;

	/*
	 * Some contexts may involve an exception occuring in an irq,
	 * leading to that nesting:
	 * rcu_irq_enter() rcu_user_exit() rcu_user_exit() rcu_irq_exit()
	 * This would mess up the dyntick_nesting count though. And rcu_irq_*()
	 * helpers are enough to protect RCU uses inside the exception. So
	 * just return immediately if we detect we are in an IRQ.
	 */
	if (in_interrupt())
		return;

	local_irq_save(flags);
	if (__this_cpu_read(context_tracking.state) == IN_USER) {
		__this_cpu_write(context_tracking.state, IN_KERNEL);
		/*
		 * We are going to run code that may use RCU. Inform
		 * RCU core about that (ie: we may need the tick again).
		 */
		rcu_user_exit();
	}
	local_irq_restore(flags);
}


/**
 * context_tracking_task_switch - context switch the syscall callbacks
 * @prev: the task that is being switched out
 * @next: the task that is being switched in
 *
 * The context tracking uses the syscall slow path to implement its user-kernel
 * boundaries probes on syscalls. This way it doesn't impact the syscall fast
 * path on CPUs that don't do context tracking.
 *
 * But we need to clear the flag on the previous task because it may later
 * migrate to some CPU that doesn't do the context tracking. As such the TIF
 * flag may not be desired there.
 */
void context_tracking_task_switch(struct task_struct *prev,
			     struct task_struct *next)
{
+7 −0
Original line number Diff line number Diff line
@@ -111,4 +111,11 @@ static inline bool __rcu_reclaim(char *rn, struct rcu_head *head)

extern int rcu_expedited;

#ifdef CONFIG_RCU_STALL_COMMON

extern int rcu_cpu_stall_suppress;
int rcu_jiffies_till_stall_check(void);

#endif /* #ifdef CONFIG_RCU_STALL_COMMON */

#endif /* __LINUX_RCU_H */
Loading