summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDipankar Sarma <dipankar@in.ibm.com>2004-08-22 22:58:16 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 22:58:16 -0700
commitf4d4d3f33efca5261c6313ead7d4b6d3a6add711 (patch)
treedad2fdbe47a125488716594bb2edf28f87b62d67 /include
parenta879f6e985b868512fb2aecf183be6caf82b7023 (diff)
[PATCH] rcu: introduce call_rcu_bh()
Introduces call_rcu_bh() to be used when critical sections are mostly in softirq context. This patch introduces a new api - call_rcu_bh(). This is to be used for RCU callbacks for whom the critical sections are mostly in softirq context. These callbacks consider completion of a softirq handler to be a quiescent state. So, in order to make reader critical sections safe in process context, rcu_read_lock_bh() and rcu_read_unlock_bh() must be used. Use of softirq handler completion as a quiescent state speeds up RCU grace periods and prevents too many callbacks getting queued up in softirq-heavy workloads like network stack. Signed-off-by: Dipankar Sarma <dipankar@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/rcupdate.h14
1 files changed, 13 insertions, 1 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 8c8157be11f7..f003f8ff9789 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -105,7 +105,9 @@ struct rcu_data {
};
DECLARE_PER_CPU(struct rcu_data, rcu_data);
+DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
extern struct rcu_ctrlblk rcu_ctrlblk;
+extern struct rcu_ctrlblk rcu_bh_ctrlblk;
/*
* Increment the quiscent state counter.
@@ -115,6 +117,11 @@ static inline void rcu_qsctr_inc(int cpu)
struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
rdp->qsctr++;
}
+static inline void rcu_bh_qsctr_inc(int cpu)
+{
+ struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu);
+ rdp->qsctr++;
+}
static inline int __rcu_pending(struct rcu_ctrlblk *rcp,
struct rcu_data *rdp)
@@ -143,11 +150,14 @@ static inline int __rcu_pending(struct rcu_ctrlblk *rcp,
static inline int rcu_pending(int cpu)
{
- return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu));
+ return __rcu_pending(&rcu_ctrlblk, &per_cpu(rcu_data, cpu)) ||
+ __rcu_pending(&rcu_bh_ctrlblk, &per_cpu(rcu_bh_data, cpu));
}
#define rcu_read_lock() preempt_disable()
#define rcu_read_unlock() preempt_enable()
+#define rcu_read_lock_bh() local_bh_disable()
+#define rcu_read_unlock_bh() local_bh_enable()
extern void rcu_init(void);
extern void rcu_check_callbacks(int cpu, int user);
@@ -156,6 +166,8 @@ extern void rcu_restart_cpu(int cpu);
/* Exported interfaces */
extern void FASTCALL(call_rcu(struct rcu_head *head,
void (*func)(struct rcu_head *head)));
+extern void FASTCALL(call_rcu_bh(struct rcu_head *head,
+ void (*func)(struct rcu_head *head)));
extern void synchronize_kernel(void);
#endif /* __KERNEL__ */