Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101362
b: refs/heads/master
c: 4446a36
h: refs/heads/master
v: v3
  • Loading branch information
Paul E. McKenney authored and Ingo Molnar committed May 19, 2008
1 parent 7a792ec commit 9086f8a
Show file tree
Hide file tree
Showing 7 changed files with 435 additions and 69 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8b09dee67f484e9b42114b1a1f068e080fd7aa56
refs/heads/master: 4446a36ff8c74ac3b32feb009b651048e129c6af
3 changes: 3 additions & 0 deletions trunk/include/linux/rcuclassic.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ extern struct lockdep_map rcu_lock_map;

#define __synchronize_sched() synchronize_rcu()

#define call_rcu_sched(head, func) call_rcu(head, func)

extern void __rcu_init(void);
#define rcu_init_sched() do { } while (0)
extern void rcu_check_callbacks(int cpu, int user);
extern void rcu_restart_cpu(int cpu);

Expand Down
22 changes: 22 additions & 0 deletions trunk/include/linux/rcupdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <linux/cpumask.h>
#include <linux/seqlock.h>
#include <linux/lockdep.h>
#include <linux/completion.h>

/**
* struct rcu_head - callback structure for use with RCU
Expand Down Expand Up @@ -168,6 +169,27 @@ struct rcu_head {
(p) = (v); \
})

/* Infrastructure to implement the synchronize_() primitives. */

struct rcu_synchronize {
struct rcu_head head;
struct completion completion;
};

extern void wakeme_after_rcu(struct rcu_head *head);

#define synchronize_rcu_xxx(name, func) \
void name(void) \
{ \
struct rcu_synchronize rcu; \
\
init_completion(&rcu.completion); \
/* Will wake me after RCU finished. */ \
func(&rcu.head, wakeme_after_rcu); \
/* Wait for it. */ \
wait_for_completion(&rcu.completion); \
}

/**
* synchronize_sched - block until all CPUs have exited any non-preemptive
* kernel code sequences.
Expand Down
42 changes: 36 additions & 6 deletions trunk/include/linux/rcupreempt.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,39 @@
#include <linux/cpumask.h>
#include <linux/seqlock.h>

#define rcu_qsctr_inc(cpu)
struct rcu_dyntick_sched {
int dynticks;
int dynticks_snap;
int sched_qs;
int sched_qs_snap;
int sched_dynticks_snap;
};

DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched);

static inline void rcu_qsctr_inc(int cpu)
{
struct rcu_dyntick_sched *rdssp = &per_cpu(rcu_dyntick_sched, cpu);

rdssp->sched_qs++;
}
#define rcu_bh_qsctr_inc(cpu)
#define call_rcu_bh(head, rcu) call_rcu(head, rcu)

/**
* call_rcu_sched - Queue RCU callback for invocation after sched grace period.
* @head: structure to be used for queueing the RCU updates.
* @func: actual update function to be invoked after the grace period
*
* The update function will be invoked some time after a full
* synchronize_sched()-style grace period elapses, in other words after
* all currently executing preempt-disabled sections of code (including
* hardirq handlers, NMI handlers, and local_irq_save() blocks) have
* completed.
*/
extern void call_rcu_sched(struct rcu_head *head,
void (*func)(struct rcu_head *head));

extern void __rcu_read_lock(void) __acquires(RCU);
extern void __rcu_read_unlock(void) __releases(RCU);
extern int rcu_pending(int cpu);
Expand All @@ -55,6 +84,7 @@ extern int rcu_needs_cpu(int cpu);
extern void __synchronize_sched(void);

extern void __rcu_init(void);
extern void rcu_init_sched(void);
extern void rcu_check_callbacks(int cpu, int user);
extern void rcu_restart_cpu(int cpu);
extern long rcu_batches_completed(void);
Expand All @@ -81,20 +111,20 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu);
struct softirq_action;

#ifdef CONFIG_NO_HZ
DECLARE_PER_CPU(long, dynticks_progress_counter);
DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched);

static inline void rcu_enter_nohz(void)
{
smp_mb(); /* CPUs seeing ++ must see prior RCU read-side crit sects */
__get_cpu_var(dynticks_progress_counter)++;
WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1);
__get_cpu_var(rcu_dyntick_sched).dynticks++;
WARN_ON(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1);
}

static inline void rcu_exit_nohz(void)
{
__get_cpu_var(dynticks_progress_counter)++;
smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */
WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1));
__get_cpu_var(rcu_dyntick_sched).dynticks++;
WARN_ON(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1));
}

#else /* CONFIG_NO_HZ */
Expand Down
1 change: 1 addition & 0 deletions trunk/init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ static void __init do_initcalls(void)
*/
static void __init do_basic_setup(void)
{
rcu_init_sched(); /* needed by module_init stage. */
/* drivers will send hotplug events */
init_workqueues();
usermodehelper_init();
Expand Down
20 changes: 2 additions & 18 deletions trunk/kernel/rcupdate.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,12 @@
#include <linux/sched.h>
#include <asm/atomic.h>
#include <linux/bitops.h>
#include <linux/completion.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/mutex.h>
#include <linux/module.h>

struct rcu_synchronize {
struct rcu_head head;
struct completion completion;
};

static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
static atomic_t rcu_barrier_cpu_count;
static DEFINE_MUTEX(rcu_barrier_mutex);
Expand All @@ -60,7 +54,7 @@ static struct completion rcu_barrier_completion;
* Awaken the corresponding synchronize_rcu() instance now that a
* grace period has elapsed.
*/
static void wakeme_after_rcu(struct rcu_head *head)
void wakeme_after_rcu(struct rcu_head *head)
{
struct rcu_synchronize *rcu;

Expand All @@ -77,17 +71,7 @@ static void wakeme_after_rcu(struct rcu_head *head)
* sections are delimited by rcu_read_lock() and rcu_read_unlock(),
* and may be nested.
*/
void synchronize_rcu(void)
{
struct rcu_synchronize rcu;

init_completion(&rcu.completion);
/* Will wake me after RCU finished */
call_rcu(&rcu.head, wakeme_after_rcu);

/* Wait for it */
wait_for_completion(&rcu.completion);
}
synchronize_rcu_xxx(synchronize_rcu, call_rcu)
EXPORT_SYMBOL_GPL(synchronize_rcu);

static void rcu_barrier_callback(struct rcu_head *notused)
Expand Down
Loading

0 comments on commit 9086f8a

Please sign in to comment.