Skip to content

Commit

Permalink
Merge branches 'bigrt.2012.09.23a', 'doctorture.2012.09.23a', 'fixes.…
Browse files Browse the repository at this point in the history
…2012.09.23a', 'hotplug.2012.09.23a' and 'idlechop.2012.09.23a' into HEAD

bigrt.2012.09.23a contains additional commits to reduce scheduling latency
	from RCU on huge systems (many hundrends or thousands of CPUs).

doctorture.2012.09.23a contains documentation changes and rcutorture fixes.

fixes.2012.09.23a contains miscellaneous fixes.

hotplug.2012.09.23a contains CPU-hotplug-related changes.

idle.2012.09.23a fixes architectures for which RCU no longer considered
	the idle loop to be a quiescent state due to earlier
	adaptive-dynticks changes.  Affected architectures are alpha,
	cris, frv, h8300, m32r, m68k, mn10300, parisc, score, xtensa,
	and ia64.
  • Loading branch information
Paul E. McKenney committed Sep 25, 2012
5 parents b17c703 + 60f5378 + 86f343b + 429227b + 93482f4 commit bda4ec9
Show file tree
Hide file tree
Showing 31 changed files with 316 additions and 261 deletions.
6 changes: 6 additions & 0 deletions Documentation/RCU/checklist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ over a rather long period of time, but improvements are always welcome!
code under the influence of preempt_disable(), you instead
need to use synchronize_irq() or synchronize_sched().

This same limitation also applies to synchronize_rcu_bh()
and synchronize_srcu(), as well as to the asynchronous and
expedited forms of the three primitives, namely call_rcu(),
call_rcu_bh(), call_srcu(), synchronize_rcu_expedited(),
synchronize_rcu_bh_expedited(), and synchronize_srcu_expedited().

12. Any lock acquired by an RCU callback must be acquired elsewhere
with softirq disabled, e.g., via spin_lock_irqsave(),
spin_lock_bh(), etc. Failing to disable irq on a given
Expand Down
16 changes: 8 additions & 8 deletions Documentation/RCU/stallwarn.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ In kernels with CONFIG_RCU_FAST_NO_HZ, even more information is
printed:

INFO: rcu_preempt detected stall on CPU
0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 drain=0 . timer=-1
0: (64628 ticks this GP) idle=dd5/3fffffffffffffff/0 drain=0 . timer not pending
(t=65000 jiffies)

The "(64628 ticks this GP)" indicates that this CPU has taken more
Expand All @@ -116,13 +116,13 @@ number between the two "/"s is the value of the nesting, which will
be a small positive number if in the idle loop and a very large positive
number (as shown above) otherwise.

For CONFIG_RCU_FAST_NO_HZ kernels, the "drain=0" indicates that the
CPU is not in the process of trying to force itself into dyntick-idle
state, the "." indicates that the CPU has not given up forcing RCU
into dyntick-idle mode (it would be "H" otherwise), and the "timer=-1"
indicates that the CPU has not recented forced RCU into dyntick-idle
mode (it would otherwise indicate the number of microseconds remaining
in this forced state).
For CONFIG_RCU_FAST_NO_HZ kernels, the "drain=0" indicates that the CPU is
not in the process of trying to force itself into dyntick-idle state, the
"." indicates that the CPU has not given up forcing RCU into dyntick-idle
mode (it would be "H" otherwise), and the "timer not pending" indicates
that the CPU has not recently forced RCU into dyntick-idle mode (it
would otherwise indicate the number of microseconds remaining in this
forced state).


Multiple Warnings From One Stall
Expand Down
9 changes: 7 additions & 2 deletions Documentation/RCU/whatisRCU.txt
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@ d. Do you need to treat NMI handlers, hardirq handlers,
and code segments with preemption disabled (whether
via preempt_disable(), local_irq_save(), local_bh_disable(),
or some other mechanism) as if they were explicit RCU readers?
If so, you need RCU-sched.
If so, RCU-sched is the only choice that will work for you.

e. Do you need RCU grace periods to complete even in the face
of softirq monopolization of one or more of the CPUs? For
Expand All @@ -884,7 +884,12 @@ f. Is your workload too update-intensive for normal use of
RCU, but inappropriate for other synchronization mechanisms?
If so, consider SLAB_DESTROY_BY_RCU. But please be careful!

g. Otherwise, use RCU.
g. Do you need read-side critical sections that are respected
even though they are in the middle of the idle loop, during
user-mode execution, or on an offlined CPU? If so, SRCU is the
only choice that will work for you.

h. Otherwise, use RCU.

Of course, this all assumes that you have determined that RCU is in fact
the right tool for your job.
Expand Down
6 changes: 5 additions & 1 deletion arch/alpha/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>

#include <asm/reg.h>
#include <asm/uaccess.h>
Expand All @@ -54,9 +55,12 @@ cpu_idle(void)
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */

rcu_idle_enter();
while (!need_resched())
cpu_relax();
schedule();

rcu_idle_exit();
schedule_preempt_disabled();
}
}

Expand Down
1 change: 1 addition & 0 deletions arch/alpha/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ smp_callin(void)
DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",
cpuid, current, current->active_mm));

preempt_disable();
/* Do nothing. */
cpu_idle();
}
Expand Down
3 changes: 3 additions & 0 deletions arch/cris/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/elfcore.h>
#include <linux/mqueue.h>
#include <linux/reboot.h>
#include <linux/rcupdate.h>

//#define DEBUG

Expand Down Expand Up @@ -74,6 +75,7 @@ void cpu_idle (void)
{
/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched()) {
void (*idle)(void);
/*
Expand All @@ -86,6 +88,7 @@ void cpu_idle (void)
idle = default_idle;
idle();
}
rcu_idle_exit();
schedule_preempt_disabled();
}
}
Expand Down
3 changes: 3 additions & 0 deletions arch/frv/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/reboot.h>
#include <linux/interrupt.h>
#include <linux/pagemap.h>
#include <linux/rcupdate.h>

#include <asm/asm-offsets.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -69,12 +70,14 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched()) {
check_pgt_cache();

if (!frv_dma_inprogress && idle)
idle();
}
rcu_idle_exit();

schedule_preempt_disabled();
}
Expand Down
3 changes: 3 additions & 0 deletions arch/h8300/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/reboot.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>

#include <asm/uaccess.h>
#include <asm/traps.h>
Expand Down Expand Up @@ -78,8 +79,10 @@ void (*idle)(void) = default_idle;
void cpu_idle(void)
{
while (1) {
rcu_idle_enter();
while (!need_resched())
idle();
rcu_idle_exit();
schedule_preempt_disabled();
}
}
Expand Down
3 changes: 3 additions & 0 deletions arch/ia64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/kdebug.h>
#include <linux/utsname.h>
#include <linux/tracehook.h>
#include <linux/rcupdate.h>

#include <asm/cpu.h>
#include <asm/delay.h>
Expand Down Expand Up @@ -279,6 +280,7 @@ cpu_idle (void)

/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
if (can_do_pal_halt) {
current_thread_info()->status &= ~TS_POLLING;
/*
Expand Down Expand Up @@ -309,6 +311,7 @@ cpu_idle (void)
normal_xtp();
#endif
}
rcu_idle_exit();
schedule_preempt_disabled();
check_pgt_cache();
if (cpu_is_offline(cpu))
Expand Down
3 changes: 3 additions & 0 deletions arch/m32r/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>

#include <asm/io.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -82,6 +83,7 @@ void cpu_idle (void)
{
/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched()) {
void (*idle)(void) = pm_idle;

Expand All @@ -90,6 +92,7 @@ void cpu_idle (void)

idle();
}
rcu_idle_exit();
schedule_preempt_disabled();
}
}
Expand Down
3 changes: 3 additions & 0 deletions arch/m68k/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/reboot.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
#include <linux/rcupdate.h>

#include <asm/uaccess.h>
#include <asm/traps.h>
Expand Down Expand Up @@ -75,8 +76,10 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched())
idle();
rcu_idle_exit();
schedule_preempt_disabled();
}
}
Expand Down
3 changes: 3 additions & 0 deletions arch/mn10300/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
Expand Down Expand Up @@ -107,6 +108,7 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
for (;;) {
rcu_idle_enter();
while (!need_resched()) {
void (*idle)(void);

Expand All @@ -121,6 +123,7 @@ void cpu_idle(void)
}
idle();
}
rcu_idle_exit();

schedule_preempt_disabled();
}
Expand Down
3 changes: 3 additions & 0 deletions arch/parisc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <linux/unistd.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/rcupdate.h>

#include <asm/io.h>
#include <asm/asm-offsets.h>
Expand All @@ -69,8 +70,10 @@ void cpu_idle(void)

/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched())
barrier();
rcu_idle_exit();
schedule_preempt_disabled();
check_pgt_cache();
}
Expand Down
4 changes: 3 additions & 1 deletion arch/score/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/reboot.h>
#include <linux/elfcore.h>
#include <linux/pm.h>
#include <linux/rcupdate.h>

void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
Expand All @@ -50,9 +51,10 @@ void __noreturn cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched())
barrier();

rcu_idle_exit();
schedule_preempt_disabled();
}
}
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kernel/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,14 @@ static int __init cpuid_init(void)
goto out_chrdev;
}
cpuid_class->devnode = cpuid_devnode;
get_online_cpus();
for_each_online_cpu(i) {
err = cpuid_device_create(i);
if (err != 0)
goto out_class;
}
register_hotcpu_notifier(&cpuid_class_cpu_notifier);
put_online_cpus();

err = 0;
goto out;
Expand All @@ -214,6 +216,7 @@ static int __init cpuid_init(void)
for_each_online_cpu(i) {
cpuid_device_destroy(i);
}
put_online_cpus();
class_destroy(cpuid_class);
out_chrdev:
__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
Expand All @@ -225,11 +228,13 @@ static void __exit cpuid_exit(void)
{
int cpu = 0;

get_online_cpus();
for_each_online_cpu(cpu)
cpuid_device_destroy(cpu);
class_destroy(cpuid_class);
__unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
put_online_cpus();
}

module_init(cpuid_init);
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kernel/msr.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,14 @@ static int __init msr_init(void)
goto out_chrdev;
}
msr_class->devnode = msr_devnode;
get_online_cpus();
for_each_online_cpu(i) {
err = msr_device_create(i);
if (err != 0)
goto out_class;
}
register_hotcpu_notifier(&msr_class_cpu_notifier);
put_online_cpus();

err = 0;
goto out;
Expand All @@ -271,6 +273,7 @@ static int __init msr_init(void)
i = 0;
for_each_online_cpu(i)
msr_device_destroy(i);
put_online_cpus();
class_destroy(msr_class);
out_chrdev:
__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
Expand All @@ -281,11 +284,13 @@ static int __init msr_init(void)
static void __exit msr_exit(void)
{
int cpu = 0;
get_online_cpus();
for_each_online_cpu(cpu)
msr_device_destroy(cpu);
class_destroy(msr_class);
__unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
unregister_hotcpu_notifier(&msr_class_cpu_notifier);
put_online_cpus();
}

module_init(msr_init);
Expand Down
3 changes: 3 additions & 0 deletions arch/xtensa/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/mqueue.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>

#include <asm/pgtable.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -110,8 +111,10 @@ void cpu_idle(void)

/* endless idle loop with no priority at all */
while (1) {
rcu_idle_enter();
while (!need_resched())
platform_idle();
rcu_idle_exit();
schedule_preempt_disabled();
}
}
Expand Down
2 changes: 2 additions & 0 deletions include/linux/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ enum
NR_SOFTIRQS
};

#define SOFTIRQ_STOP_IDLE_MASK (~(1 << RCU_SOFTIRQ))

/* map softirq index to softirq name. update 'softirq_to_name' in
* kernel/softirq.c when adding a new softirq.
*/
Expand Down
Loading

0 comments on commit bda4ec9

Please sign in to comment.