forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/l…
…inux/kernel/git/tip/linux-2.6-tip * 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: rcu: Fix whitespace inconsistencies rcu: Fix thinko, actually initialize full tree rcu: Apply results of code inspection of kernel/rcutree_plugin.h rcu: Add WARN_ON_ONCE() consistency checks covering state transitions rcu: Fix synchronize_rcu() for TREE_PREEMPT_RCU rcu: Simplify rcu_read_unlock_special() quiescent-state accounting rcu: Add debug checks to TREE_PREEMPT_RCU for premature grace periods rcu: Kconfig help needs to say that TREE_PREEMPT_RCU scales down rcutorture: Occasionally delay readers enough to make RCU force_quiescent_state rcu: Initialize multi-level RCU grace periods holding locks rcu: Need to update rnp->gpnum if preemptable RCU is to be reliable
- Loading branch information
Showing
11 changed files
with
195 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Read-Copy Update mechanism for mutual exclusion | ||
* Read-Copy Update mechanism for mutual exclusion | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
|
@@ -18,15 +18,15 @@ | |
* Copyright IBM Corporation, 2001 | ||
* | ||
* Author: Dipankar Sarma <[email protected]> | ||
* | ||
* | ||
* Based on the original work by Paul McKenney <[email protected]> | ||
* and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. | ||
* Papers: | ||
* http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf | ||
* http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001) | ||
* | ||
* For detailed explanation of Read-Copy Update mechanism see - | ||
* http://lse.sourceforge.net/locking/rcupdate.html | ||
* http://lse.sourceforge.net/locking/rcupdate.html | ||
* | ||
*/ | ||
|
||
|
@@ -52,8 +52,13 @@ struct rcu_head { | |
}; | ||
|
||
/* Exported common interfaces */ | ||
#ifdef CONFIG_TREE_PREEMPT_RCU | ||
extern void synchronize_rcu(void); | ||
#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | ||
#define synchronize_rcu synchronize_sched | ||
#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */ | ||
extern void synchronize_rcu_bh(void); | ||
extern void synchronize_sched(void); | ||
extern void rcu_barrier(void); | ||
extern void rcu_barrier_bh(void); | ||
extern void rcu_barrier_sched(void); | ||
|
@@ -261,24 +266,6 @@ struct rcu_synchronize { | |
|
||
extern void wakeme_after_rcu(struct rcu_head *head); | ||
|
||
/** | ||
* synchronize_sched - block until all CPUs have exited any non-preemptive | ||
* kernel code sequences. | ||
* | ||
* This means that all preempt_disable code sequences, including NMI and | ||
* hardware-interrupt handlers, in progress on entry will have completed | ||
* before this primitive returns. However, this does not guarantee that | ||
* softirq handlers will have completed, since in some kernels, these | ||
* handlers can run in process context, and can block. | ||
* | ||
* This primitive provides the guarantees made by the (now removed) | ||
* synchronize_kernel() API. In contrast, synchronize_rcu() only | ||
* guarantees that rcu_read_lock() sections will have completed. | ||
* In "classic RCU", these two guarantees happen to be one and | ||
* the same, but can differ in realtime RCU implementations. | ||
*/ | ||
#define synchronize_sched() __synchronize_sched() | ||
|
||
/** | ||
* call_rcu - Queue an RCU callback for invocation after a grace period. | ||
* @head: structure to be used for queueing the RCU updates. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,15 +19,15 @@ | |
* | ||
* Authors: Dipankar Sarma <[email protected]> | ||
* Manfred Spraul <[email protected]> | ||
* | ||
* | ||
* Based on the original work by Paul McKenney <[email protected]> | ||
* and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. | ||
* Papers: | ||
* http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf | ||
* http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001) | ||
* | ||
* For detailed explanation of Read-Copy Update mechanism see - | ||
* http://lse.sourceforge.net/locking/rcupdate.html | ||
* http://lse.sourceforge.net/locking/rcupdate.html | ||
* | ||
*/ | ||
#include <linux/types.h> | ||
|
@@ -74,6 +74,8 @@ void wakeme_after_rcu(struct rcu_head *head) | |
complete(&rcu->completion); | ||
} | ||
|
||
#ifdef CONFIG_TREE_PREEMPT_RCU | ||
|
||
/** | ||
* synchronize_rcu - wait until a grace period has elapsed. | ||
* | ||
|
@@ -87,7 +89,7 @@ void synchronize_rcu(void) | |
{ | ||
struct rcu_synchronize rcu; | ||
|
||
if (rcu_blocking_is_gp()) | ||
if (!rcu_scheduler_active) | ||
return; | ||
|
||
init_completion(&rcu.completion); | ||
|
@@ -98,6 +100,46 @@ void synchronize_rcu(void) | |
} | ||
EXPORT_SYMBOL_GPL(synchronize_rcu); | ||
|
||
#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ | ||
|
||
/** | ||
* synchronize_sched - wait until an rcu-sched grace period has elapsed. | ||
* | ||
* Control will return to the caller some time after a full rcu-sched | ||
* grace period has elapsed, in other words after all currently executing | ||
* rcu-sched read-side critical sections have completed. These read-side | ||
* critical sections are delimited by rcu_read_lock_sched() and | ||
* rcu_read_unlock_sched(), and may be nested. Note that preempt_disable(), | ||
* local_irq_disable(), and so on may be used in place of | ||
* rcu_read_lock_sched(). | ||
* | ||
* This means that all preempt_disable code sequences, including NMI and | ||
* hardware-interrupt handlers, in progress on entry will have completed | ||
* before this primitive returns. However, this does not guarantee that | ||
* softirq handlers will have completed, since in some kernels, these | ||
* handlers can run in process context, and can block. | ||
* | ||
* This primitive provides the guarantees made by the (now removed) | ||
* synchronize_kernel() API. In contrast, synchronize_rcu() only | ||
* guarantees that rcu_read_lock() sections will have completed. | ||
* In "classic RCU", these two guarantees happen to be one and | ||
* the same, but can differ in realtime RCU implementations. | ||
*/ | ||
void synchronize_sched(void) | ||
{ | ||
struct rcu_synchronize rcu; | ||
|
||
if (rcu_blocking_is_gp()) | ||
return; | ||
|
||
init_completion(&rcu.completion); | ||
/* Will wake me after RCU finished. */ | ||
call_rcu_sched(&rcu.head, wakeme_after_rcu); | ||
/* Wait for it. */ | ||
wait_for_completion(&rcu.completion); | ||
} | ||
EXPORT_SYMBOL_GPL(synchronize_sched); | ||
|
||
/** | ||
* synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. | ||
* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
* Copyright (C) IBM Corporation, 2005, 2006 | ||
* | ||
* Authors: Paul E. McKenney <[email protected]> | ||
* Josh Triplett <[email protected]> | ||
* Josh Triplett <[email protected]> | ||
* | ||
* See also: Documentation/RCU/torture.txt | ||
*/ | ||
|
@@ -50,7 +50,7 @@ | |
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Paul E. McKenney <[email protected]> and " | ||
"Josh Triplett <[email protected]>"); | ||
"Josh Triplett <[email protected]>"); | ||
|
||
static int nreaders = -1; /* # reader threads, defaults to 2*ncpus */ | ||
static int nfakewriters = 4; /* # fake writer threads */ | ||
|
@@ -110,8 +110,8 @@ struct rcu_torture { | |
}; | ||
|
||
static LIST_HEAD(rcu_torture_freelist); | ||
static struct rcu_torture *rcu_torture_current = NULL; | ||
static long rcu_torture_current_version = 0; | ||
static struct rcu_torture *rcu_torture_current; | ||
static long rcu_torture_current_version; | ||
static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN]; | ||
static DEFINE_SPINLOCK(rcu_torture_lock); | ||
static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) = | ||
|
@@ -124,11 +124,11 @@ static atomic_t n_rcu_torture_alloc_fail; | |
static atomic_t n_rcu_torture_free; | ||
static atomic_t n_rcu_torture_mberror; | ||
static atomic_t n_rcu_torture_error; | ||
static long n_rcu_torture_timers = 0; | ||
static long n_rcu_torture_timers; | ||
static struct list_head rcu_torture_removed; | ||
static cpumask_var_t shuffle_tmp_mask; | ||
|
||
static int stutter_pause_test = 0; | ||
static int stutter_pause_test; | ||
|
||
#if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE) | ||
#define RCUTORTURE_RUNNABLE_INIT 1 | ||
|
@@ -267,7 +267,8 @@ struct rcu_torture_ops { | |
int irq_capable; | ||
char *name; | ||
}; | ||
static struct rcu_torture_ops *cur_ops = NULL; | ||
|
||
static struct rcu_torture_ops *cur_ops; | ||
|
||
/* | ||
* Definitions for rcu torture testing. | ||
|
@@ -281,14 +282,17 @@ static int rcu_torture_read_lock(void) __acquires(RCU) | |
|
||
static void rcu_read_delay(struct rcu_random_state *rrsp) | ||
{ | ||
long delay; | ||
const long longdelay = 200; | ||
const unsigned long shortdelay_us = 200; | ||
const unsigned long longdelay_ms = 50; | ||
|
||
/* We want there to be long-running readers, but not all the time. */ | ||
/* We want a short delay sometimes to make a reader delay the grace | ||
* period, and we want a long delay occasionally to trigger | ||
* force_quiescent_state. */ | ||
|
||
delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay); | ||
if (!delay) | ||
udelay(longdelay); | ||
if (!(rcu_random(rrsp) % (nrealreaders * 2000 * longdelay_ms))) | ||
mdelay(longdelay_ms); | ||
if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us))) | ||
udelay(shortdelay_us); | ||
} | ||
|
||
static void rcu_torture_read_unlock(int idx) __releases(RCU) | ||
|
@@ -339,8 +343,8 @@ static struct rcu_torture_ops rcu_ops = { | |
.sync = synchronize_rcu, | ||
.cb_barrier = rcu_barrier, | ||
.stats = NULL, | ||
.irq_capable = 1, | ||
.name = "rcu" | ||
.irq_capable = 1, | ||
.name = "rcu" | ||
}; | ||
|
||
static void rcu_sync_torture_deferred_free(struct rcu_torture *p) | ||
|
@@ -638,7 +642,8 @@ rcu_torture_writer(void *arg) | |
|
||
do { | ||
schedule_timeout_uninterruptible(1); | ||
if ((rp = rcu_torture_alloc()) == NULL) | ||
rp = rcu_torture_alloc(); | ||
if (rp == NULL) | ||
continue; | ||
rp->rtort_pipe_count = 0; | ||
udelay(rcu_random(&rand) & 0x3ff); | ||
|
@@ -1110,7 +1115,7 @@ rcu_torture_init(void) | |
printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n", | ||
torture_type); | ||
mutex_unlock(&fullstop_mutex); | ||
return (-EINVAL); | ||
return -EINVAL; | ||
} | ||
if (cur_ops->init) | ||
cur_ops->init(); /* no "goto unwind" prior to this point!!! */ | ||
|
@@ -1161,7 +1166,7 @@ rcu_torture_init(void) | |
goto unwind; | ||
} | ||
fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]), | ||
GFP_KERNEL); | ||
GFP_KERNEL); | ||
if (fakewriter_tasks == NULL) { | ||
VERBOSE_PRINTK_ERRSTRING("out of memory"); | ||
firsterr = -ENOMEM; | ||
|
@@ -1170,7 +1175,7 @@ rcu_torture_init(void) | |
for (i = 0; i < nfakewriters; i++) { | ||
VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task"); | ||
fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL, | ||
"rcu_torture_fakewriter"); | ||
"rcu_torture_fakewriter"); | ||
if (IS_ERR(fakewriter_tasks[i])) { | ||
firsterr = PTR_ERR(fakewriter_tasks[i]); | ||
VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter"); | ||
|
Oops, something went wrong.