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

Commit 7b0b759b authored by Paul E. McKenney's avatar Paul E. McKenney
Browse files

rcu: combine duplicate code, courtesy of CONFIG_PREEMPT_RCU



The CONFIG_PREEMPT_RCU kernel configuration parameter was recently
re-introduced, but as an indication of the type of RCU (preemptible
vs. non-preemptible) instead of as selecting a given implementation.
This commit uses CONFIG_PREEMPT_RCU to combine duplicate code
from include/linux/rcutiny.h and include/linux/rcutree.h into
include/linux/rcupdate.h.  This commit also combines a few other pieces
of duplicate code that have accumulated.

Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
parent 73d4da4d
Loading
Loading
Loading
Loading
+72 −3
Original line number Original line Diff line number Diff line
@@ -61,16 +61,30 @@ struct rcu_head {
};
};


/* Exported common interfaces */
/* Exported common interfaces */
extern void call_rcu_sched(struct rcu_head *head,
			   void (*func)(struct rcu_head *rcu));
extern void synchronize_sched(void);
extern void rcu_barrier_bh(void);
extern void rcu_barrier_bh(void);
extern void rcu_barrier_sched(void);
extern void rcu_barrier_sched(void);
extern void synchronize_sched_expedited(void);
extern void synchronize_sched_expedited(void);
extern int sched_expedited_torture_stats(char *page);
extern int sched_expedited_torture_stats(char *page);


/* Internal to kernel */
static inline void __rcu_read_lock_bh(void)
extern void rcu_init(void);
{
	local_bh_disable();
}

static inline void __rcu_read_unlock_bh(void)
{
	local_bh_enable();
}


#ifdef CONFIG_PREEMPT_RCU
#ifdef CONFIG_PREEMPT_RCU


extern void __rcu_read_lock(void);
extern void __rcu_read_unlock(void);
void synchronize_rcu(void);

/*
/*
 * Defined as a macro as it is a very low level header included from
 * Defined as a macro as it is a very low level header included from
 * areas that don't even know about current.  This gives the rcu_read_lock()
 * areas that don't even know about current.  This gives the rcu_read_lock()
@@ -79,7 +93,53 @@ extern void rcu_init(void);
 */
 */
#define rcu_preempt_depth() (current->rcu_read_lock_nesting)
#define rcu_preempt_depth() (current->rcu_read_lock_nesting)


#endif /* #ifdef CONFIG_PREEMPT_RCU */
#else /* #ifdef CONFIG_PREEMPT_RCU */

static inline void __rcu_read_lock(void)
{
	preempt_disable();
}

static inline void __rcu_read_unlock(void)
{
	preempt_enable();
}

static inline void synchronize_rcu(void)
{
	synchronize_sched();
}

static inline int rcu_preempt_depth(void)
{
	return 0;
}

#endif /* #else #ifdef CONFIG_PREEMPT_RCU */

/* Internal to kernel */
extern void rcu_init(void);
extern void rcu_sched_qs(int cpu);
extern void rcu_bh_qs(int cpu);
extern void rcu_check_callbacks(int cpu, int user);
struct notifier_block;

#ifdef CONFIG_NO_HZ

extern void rcu_enter_nohz(void);
extern void rcu_exit_nohz(void);

#else /* #ifdef CONFIG_NO_HZ */

static inline void rcu_enter_nohz(void)
{
}

static inline void rcu_exit_nohz(void)
{
}

#endif /* #else #ifdef CONFIG_NO_HZ */


#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
#if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
#include <linux/rcutree.h>
#include <linux/rcutree.h>
@@ -626,6 +686,8 @@ struct rcu_synchronize {


extern void wakeme_after_rcu(struct rcu_head  *head);
extern void wakeme_after_rcu(struct rcu_head  *head);


#ifdef CONFIG_PREEMPT_RCU

/**
/**
 * call_rcu() - Queue an RCU callback for invocation after a grace period.
 * call_rcu() - Queue an RCU callback for invocation after a grace period.
 * @head: structure to be used for queueing the RCU updates.
 * @head: structure to be used for queueing the RCU updates.
@@ -642,6 +704,13 @@ extern void wakeme_after_rcu(struct rcu_head *head);
extern void call_rcu(struct rcu_head *head,
extern void call_rcu(struct rcu_head *head,
			      void (*func)(struct rcu_head *head));
			      void (*func)(struct rcu_head *head));


#else /* #ifdef CONFIG_PREEMPT_RCU */

/* In classic RCU, call_rcu() is just call_rcu_sched(). */
#define	call_rcu	call_rcu_sched

#endif /* #else #ifdef CONFIG_PREEMPT_RCU */

/**
/**
 * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
 * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period.
 * @head: structure to be used for queueing the RCU updates.
 * @head: structure to be used for queueing the RCU updates.
+0 −51
Original line number Original line Diff line number Diff line
@@ -27,34 +27,10 @@


#include <linux/cache.h>
#include <linux/cache.h>


void rcu_sched_qs(int cpu);
void rcu_bh_qs(int cpu);

#ifdef CONFIG_TINY_RCU
#define __rcu_read_lock()	preempt_disable()
#define __rcu_read_unlock()	preempt_enable()
#else /* #ifdef CONFIG_TINY_RCU */
void __rcu_read_lock(void);
void __rcu_read_unlock(void);
#endif /* #else #ifdef CONFIG_TINY_RCU */
#define __rcu_read_lock_bh()	local_bh_disable()
#define __rcu_read_unlock_bh()	local_bh_enable()
extern void call_rcu_sched(struct rcu_head *head,
			   void (*func)(struct rcu_head *rcu));

#define rcu_init_sched()	do { } while (0)
#define rcu_init_sched()	do { } while (0)


extern void synchronize_sched(void);

#ifdef CONFIG_TINY_RCU
#ifdef CONFIG_TINY_RCU


#define call_rcu		call_rcu_sched

static inline void synchronize_rcu(void)
{
	synchronize_sched();
}

static inline void synchronize_rcu_expedited(void)
static inline void synchronize_rcu_expedited(void)
{
{
	synchronize_sched();	/* Only one CPU, so pretty fast anyway!!! */
	synchronize_sched();	/* Only one CPU, so pretty fast anyway!!! */
@@ -67,7 +43,6 @@ static inline void rcu_barrier(void)


#else /* #ifdef CONFIG_TINY_RCU */
#else /* #ifdef CONFIG_TINY_RCU */


void synchronize_rcu(void);
void rcu_barrier(void);
void rcu_barrier(void);
void synchronize_rcu_expedited(void);
void synchronize_rcu_expedited(void);


@@ -83,25 +58,6 @@ static inline void synchronize_rcu_bh_expedited(void)
	synchronize_sched();
	synchronize_sched();
}
}


struct notifier_block;

#ifdef CONFIG_NO_HZ

extern void rcu_enter_nohz(void);
extern void rcu_exit_nohz(void);

#else /* #ifdef CONFIG_NO_HZ */

static inline void rcu_enter_nohz(void)
{
}

static inline void rcu_exit_nohz(void)
{
}

#endif /* #else #ifdef CONFIG_NO_HZ */

#ifdef CONFIG_TINY_RCU
#ifdef CONFIG_TINY_RCU


static inline void rcu_preempt_note_context_switch(void)
static inline void rcu_preempt_note_context_switch(void)
@@ -117,11 +73,6 @@ static inline int rcu_needs_cpu(int cpu)
	return 0;
	return 0;
}
}


static inline int rcu_preempt_depth(void)
{
	return 0;
}

#else /* #ifdef CONFIG_TINY_RCU */
#else /* #ifdef CONFIG_TINY_RCU */


void rcu_preempt_note_context_switch(void);
void rcu_preempt_note_context_switch(void);
@@ -141,8 +92,6 @@ static inline void rcu_note_context_switch(int cpu)
	rcu_preempt_note_context_switch();
	rcu_preempt_note_context_switch();
}
}


extern void rcu_check_callbacks(int cpu, int user);

/*
/*
 * Return the number of grace periods.
 * Return the number of grace periods.
 */
 */
+0 −50
Original line number Original line Diff line number Diff line
@@ -30,59 +30,23 @@
#ifndef __LINUX_RCUTREE_H
#ifndef __LINUX_RCUTREE_H
#define __LINUX_RCUTREE_H
#define __LINUX_RCUTREE_H


struct notifier_block;

extern void rcu_sched_qs(int cpu);
extern void rcu_bh_qs(int cpu);
extern void rcu_note_context_switch(int cpu);
extern void rcu_note_context_switch(int cpu);
extern int rcu_needs_cpu(int cpu);
extern int rcu_needs_cpu(int cpu);
extern void rcu_cpu_stall_reset(void);
extern void rcu_cpu_stall_reset(void);


#ifdef CONFIG_TREE_PREEMPT_RCU
#ifdef CONFIG_TREE_PREEMPT_RCU


extern void __rcu_read_lock(void);
extern void __rcu_read_unlock(void);
extern void synchronize_rcu(void);
extern void exit_rcu(void);
extern void exit_rcu(void);


#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */


static inline void __rcu_read_lock(void)
{
	preempt_disable();
}

static inline void __rcu_read_unlock(void)
{
	preempt_enable();
}

#define synchronize_rcu synchronize_sched

static inline void exit_rcu(void)
static inline void exit_rcu(void)
{
{
}
}


static inline int rcu_preempt_depth(void)
{
	return 0;
}

#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */


static inline void __rcu_read_lock_bh(void)
{
	local_bh_disable();
}
static inline void __rcu_read_unlock_bh(void)
{
	local_bh_enable();
}

extern void call_rcu_sched(struct rcu_head *head,
			   void (*func)(struct rcu_head *rcu));
extern void synchronize_rcu_bh(void);
extern void synchronize_rcu_bh(void);
extern void synchronize_sched(void);
extern void synchronize_rcu_expedited(void);
extern void synchronize_rcu_expedited(void);


static inline void synchronize_rcu_bh_expedited(void)
static inline void synchronize_rcu_bh_expedited(void)
@@ -92,8 +56,6 @@ static inline void synchronize_rcu_bh_expedited(void)


extern void rcu_barrier(void);
extern void rcu_barrier(void);


extern void rcu_check_callbacks(int cpu, int user);

extern long rcu_batches_completed(void);
extern long rcu_batches_completed(void);
extern long rcu_batches_completed_bh(void);
extern long rcu_batches_completed_bh(void);
extern long rcu_batches_completed_sched(void);
extern long rcu_batches_completed_sched(void);
@@ -101,18 +63,6 @@ extern void rcu_force_quiescent_state(void);
extern void rcu_bh_force_quiescent_state(void);
extern void rcu_bh_force_quiescent_state(void);
extern void rcu_sched_force_quiescent_state(void);
extern void rcu_sched_force_quiescent_state(void);


#ifdef CONFIG_NO_HZ
void rcu_enter_nohz(void);
void rcu_exit_nohz(void);
#else /* CONFIG_NO_HZ */
static inline void rcu_enter_nohz(void)
{
}
static inline void rcu_exit_nohz(void)
{
}
#endif /* CONFIG_NO_HZ */

/* A context switch is a grace period for RCU-sched and RCU-bh. */
/* A context switch is a grace period for RCU-sched and RCU-bh. */
static inline int rcu_blocking_is_gp(void)
static inline int rcu_blocking_is_gp(void)
{
{
+0 −9
Original line number Original line Diff line number Diff line
@@ -938,15 +938,6 @@ static void rcu_preempt_process_callbacks(void)
{
{
}
}


/*
 * In classic RCU, call_rcu() is just call_rcu_sched().
 */
void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
{
	call_rcu_sched(head, func);
}
EXPORT_SYMBOL_GPL(call_rcu);

/*
/*
 * Wait for an rcu-preempt grace period, but make it happen quickly.
 * Wait for an rcu-preempt grace period, but make it happen quickly.
 * But because preemptable RCU does not exist, map to rcu-sched.
 * But because preemptable RCU does not exist, map to rcu-sched.