Skip to contentSkip to conversation

rcupdate: move synchronize_sched() back to rcupdate.c V2

PATCH In review Lai Jiangshan 4 participants 16 messages Nov 6, 2008 – Nov 17, 2008

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 rcupdate: move synchronize_sched() back to rcupdate.c V2

this fix remove ugly macro, and increase readability for rcupdate codes

changed from v1:
use HAVE_SPECIAL_RCU_BH/SCHED instead of define duplicate version of synchronize_sched().

---

include/linux/rcuclassic.h +1 -5
index 5f89b62..68e84ff 100644
@@ -32,6 +32,7 @@
 
 #ifndef __LINUX_RCUCLASSIC_H
 #define __LINUX_RCUCLASSIC_H
+#define HAVE_SPECIAL_RCU_BH
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
@@ -166,12 +167,7 @@ extern struct lockdep_map rcu_lock_map;
 		local_bh_enable(); \
 	} while (0)
 
-#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);
 
include/linux/rcupdate.h +51 -43

132 lines not on this page · raw message

include/linux/rcupreempt.h +1 -36
index 3e05c09..f30d1c8 100644
@@ -32,6 +32,7 @@
 
 #ifndef __LINUX_RCUPREEMPT_H
 #define __LINUX_RCUPREEMPT_H
+#define HAVE_SPECIAL_RCU_SCHED
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
@@ -56,54 +57,18 @@ static inline void rcu_qsctr_inc(int cpu)
 
 	rdssp->sched_qs++;
 }
-#define rcu_bh_qsctr_inc(cpu)
-
-/*
- * Someone might want to pass call_rcu_bh as a function pointer.
- * So this needs to just be a rename and not a macro function.
- *  (no parentheses)
- */
-#define call_rcu_bh	 	call_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);
 extern int rcu_needs_cpu(int cpu);
 
-#define __rcu_read_lock_bh()	{ rcu_read_lock(); local_bh_disable(); }
-#define __rcu_read_unlock_bh()	{ local_bh_enable(); rcu_read_unlock(); }
-
-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);
 
-/*
- * Return the number of RCU batches processed thus far. Useful for debug
- * and statistic. The _bh variant is identifcal to straight RCU
- */
-static inline long rcu_batches_completed_bh(void)
-{
-	return rcu_batches_completed();
-}
-
 #ifdef CONFIG_RCU_TRACE
 struct rcupreempt_trace;
 extern long *rcupreempt_flipctr(int cpu);
kernel/rcupdate.c +50 -3

90 lines not on this page · raw message

kernel/rcupreempt.c +0 -9
index 59236e8..2068ad9 100644
@@ -1161,15 +1161,6 @@ void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 EXPORT_SYMBOL_GPL(call_rcu_sched);
 
 /*
- * Wait until all currently running preempt_disable() code segments
- * (including hardware-irq-disable segments) complete.  Note that
- * in -rt this does -not- necessarily result in all currently executing
- * interrupt -handlers- having completed.
- */
-synchronize_rcu_xxx(__synchronize_sched, call_rcu_sched)
-EXPORT_SYMBOL_GPL(__synchronize_sched);
-
-/*
  * kthread function that manages call_rcu_sched grace periods.
  */
 static int rcu_sched_grace_period(void *arg)
#1 lore raw
Quoted 1 line · Lai Jiangshan

this fix remove ugly macro, and increase readability for rcupdate codes

looks good to me, if Paul acks the concept too.

Two small details:

include/linux/rcuclassic.h line 35

Quoted 6 lines

+++ b/include/linux/rcuclassic.h

include/linux/rcuclassic.h +1 -0
@@ -32,6 +32,7 @@
 
 #ifndef __LINUX_RCUCLASSIC_H
 #define __LINUX_RCUCLASSIC_H
+#define HAVE_SPECIAL_RCU_BH

please use def_bool to define CONFIG_RCU_HAVE_SPECIAL_RCU_BH

and:

include/linux/rcupdate.h struct rcu_head { · line 140

Quoted 5 lines
include/linux/rcupdate.h +5 -0
+#else
+#define rcu_bh_qsctr_inc(cpu)
+#define rcu_read_lock_bh()	{ rcu_read_lock(); local_bh_disable(); }
+#define rcu_read_unlock_bh()	{ local_bh_enable(); rcu_read_unlock(); }
+#endif /* HAVE_SPECIAL_RCU_BH */

use inline functions please. CPP defines should never be used in new code. (use inlines instead of macros and enums/const instead of constant #define's)

Ingo

#2 lore raw
In reply to Lai Jiangshan
Quoted 6 lines · Lai Jiangshan

this fix remove ugly macro, and increase readability for rcupdate codes

changed from v1:
use HAVE_SPECIAL_RCU_BH/SCHED instead of define duplicate version of synchronize_sched().

Hello, Jiangshan!

I very much like getting rid of the ugly macro. I of course like the kernel-doc fixes. ;-)

I am not yet convinced of the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED pieces. It is not clear to me that this approach is simpler than the current approach of simply providing the appropriate definitions for the symbols in the implementation-specific rcuxxx.h file.

Am I missing something?

Thanx, Paul

Quoted 356 lines

---

include/linux/rcuclassic.h +1 -5
index 5f89b62..68e84ff 100644
@@ -32,6 +32,7 @@
 
 #ifndef __LINUX_RCUCLASSIC_H
 #define __LINUX_RCUCLASSIC_H
+#define HAVE_SPECIAL_RCU_BH
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
@@ -166,12 +167,7 @@ extern struct lockdep_map rcu_lock_map;
 		local_bh_enable(); \
 	} while (0)
 
-#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);
 
include/linux/rcupdate.h +51 -43
index 86f1f5e..7861bee 100644
@@ -112,6 +112,7 @@ struct rcu_head {
  */
 #define rcu_read_unlock() __rcu_read_unlock()
 
+#ifdef HAVE_SPECIAL_RCU_BH
 /**
  * rcu_read_lock_bh - mark the beginning of a softirq-only RCU critical section
  *
@@ -125,13 +126,19 @@ struct rcu_head {
  */
 #define rcu_read_lock_bh() __rcu_read_lock_bh()
 
-/*
+/**
  * rcu_read_unlock_bh - marks the end of a softirq-only RCU critical section
  *
  * See rcu_read_lock_bh() for more information.
  */
 #define rcu_read_unlock_bh() __rcu_read_unlock_bh()
 
+#else
+#define rcu_bh_qsctr_inc(cpu)
+#define rcu_read_lock_bh()	{ rcu_read_lock(); local_bh_disable(); }
+#define rcu_read_unlock_bh()	{ local_bh_enable(); rcu_read_unlock(); }
+#endif /* HAVE_SPECIAL_RCU_BH */
+
 /**
  * rcu_read_lock_sched - mark the beginning of a RCU-classic critical section
  *
@@ -189,45 +196,6 @@ 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.
- *
- * 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.
@@ -242,6 +210,11 @@ void name(void) \
 extern void call_rcu(struct rcu_head *head,
 			      void (*func)(struct rcu_head *head));
 
+
+extern void synchronize_rcu(void);
+extern void rcu_barrier(void);
+
+#ifdef HAVE_SPECIAL_RCU_BH
 /**
  * call_rcu_bh - Queue an RCU for invocation after a quicker grace period.
  * @head: structure to be used for queueing the RCU updates.
@@ -263,11 +236,46 @@ extern void call_rcu(struct rcu_head *head,
 extern void call_rcu_bh(struct rcu_head *head,
 			void (*func)(struct rcu_head *head));
 
-/* Exported common interfaces */
-extern void synchronize_rcu(void);
-extern void rcu_barrier(void);
 extern void rcu_barrier_bh(void);
+#else
+
+#define call_rcu_bh call_rcu
+#define rcu_barrier_bh rcu_barrier
+
+/*
+ * Return the number of RCU batches processed thus far. Useful for debug
+ * and statistic. The _bh variant is identifcal to straight RCU
+ */
+static inline long rcu_batches_completed_bh(void)
+{
+	return rcu_batches_completed();
+}
+#endif /* HAVE_SPECIAL_RCU_BH */
+
+#ifdef HAVE_SPECIAL_RCU_SCHED
+/**
+ * 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 synchronize_sched(void);
 extern void rcu_barrier_sched(void);
+#else
+#define call_rcu_sched call_rcu
+#define synchronize_sched synchronize_rcu
+#define rcu_barrier_sched rcu_barrier
+
+#define rcu_init_sched()	do { } while (0)
+#endif /* HAVE_SPECIAL_RCU_SCHED */
 
 /* Internal to kernel */
 extern void rcu_init(void);
include/linux/rcupreempt.h +1 -36
index 3e05c09..f30d1c8 100644
@@ -32,6 +32,7 @@
 
 #ifndef __LINUX_RCUPREEMPT_H
 #define __LINUX_RCUPREEMPT_H
+#define HAVE_SPECIAL_RCU_SCHED
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
@@ -56,54 +57,18 @@ static inline void rcu_qsctr_inc(int cpu)
 
 	rdssp->sched_qs++;
 }
-#define rcu_bh_qsctr_inc(cpu)
-
-/*
- * Someone might want to pass call_rcu_bh as a function pointer.
- * So this needs to just be a rename and not a macro function.
- *  (no parentheses)
- */
-#define call_rcu_bh	 	call_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);
 extern int rcu_needs_cpu(int cpu);
 
-#define __rcu_read_lock_bh()	{ rcu_read_lock(); local_bh_disable(); }
-#define __rcu_read_unlock_bh()	{ local_bh_enable(); rcu_read_unlock(); }
-
-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);
 
-/*
- * Return the number of RCU batches processed thus far. Useful for debug
- * and statistic. The _bh variant is identifcal to straight RCU
- */
-static inline long rcu_batches_completed_bh(void)
-{
-	return rcu_batches_completed();
-}
-
 #ifdef CONFIG_RCU_TRACE
 struct rcupreempt_trace;
 extern long *rcupreempt_flipctr(int cpu);
kernel/rcupdate.c +50 -3
index ad63af8..70cff32 100644
@@ -56,11 +56,16 @@ static atomic_t rcu_barrier_cpu_count;
 static DEFINE_MUTEX(rcu_barrier_mutex);
 static struct completion rcu_barrier_completion;
 
+struct rcu_synchronize {
+	struct rcu_head head;
+	struct completion completion;
+};
+
 /*
  * Awaken the corresponding synchronize_rcu() instance now that a
  * grace period has elapsed.
  */
-void wakeme_after_rcu(struct rcu_head  *head)
+static void wakeme_after_rcu(struct rcu_head  *head)
 {
 	struct rcu_synchronize *rcu;
 
@@ -77,10 +82,48 @@ 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);	/* Makes kernel-doc tools happy */
-synchronize_rcu_xxx(synchronize_rcu, call_rcu)
+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);
+}
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
+#ifdef HAVE_SPECIAL_RCU_SCHED
+/**
+ * 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.
+ */
+void synchronize_sched(void)
+{
+	struct rcu_synchronize rcu;
+
+	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);
+#endif /* HAVE_SPECIAL_RCU_SCHED */
+
 static void rcu_barrier_callback(struct rcu_head *notused)
 {
 	if (atomic_dec_and_test(&rcu_barrier_cpu_count))
@@ -145,6 +188,7 @@ void rcu_barrier(void)
 }
 EXPORT_SYMBOL_GPL(rcu_barrier);
 
+#ifdef HAVE_SPECIAL_RCU_BH
 /**
  * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
  */
@@ -153,7 +197,9 @@ void rcu_barrier_bh(void)
 	_rcu_barrier(RCU_BARRIER_BH);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_bh);
+#endif /* HAVE_SPECIAL_RCU_BH */
 
+#ifdef HAVE_SPECIAL_RCU_SCHED
 /**
  * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
  */
@@ -162,6 +208,7 @@ void rcu_barrier_sched(void)
 	_rcu_barrier(RCU_BARRIER_SCHED);
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_sched);
+#endif /* HAVE_SPECIAL_RCU_SCHED */
 
 void __init rcu_init(void)
 {
kernel/rcupreempt.c +0 -9
index 59236e8..2068ad9 100644
@@ -1161,15 +1161,6 @@ void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 EXPORT_SYMBOL_GPL(call_rcu_sched);
 
 /*
- * Wait until all currently running preempt_disable() code segments
- * (including hardware-irq-disable segments) complete.  Note that
- * in -rt this does -not- necessarily result in all currently executing
- * interrupt -handlers- having completed.
- */
-synchronize_rcu_xxx(__synchronize_sched, call_rcu_sched)
-EXPORT_SYMBOL_GPL(__synchronize_sched);
-
-/*
  * kthread function that manages call_rcu_sched grace periods.
  */
 static int rcu_sched_grace_period(void *arg)
#3 lore raw
Quoted 18 lines · Paul E. McKenney
Quoted 5 lines · Lai Jiangshan

this fix remove ugly macro, and increase readability for rcupdate codes

changed from v1:
use HAVE_SPECIAL_RCU_BH/SCHED instead of define duplicate version of synchronize_sched().

Hello, Jiangshan!

I very much like getting rid of the ugly macro. I of course like the kernel-doc fixes. ;-)

I am not yet convinced of the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED pieces. It is not clear to me that this approach is simpler than the current approach of simply providing the appropriate definitions for the symbols in the implementation-specific rcuxxx.h file.

Quoted 4 lines

Am I missing something?

Thanx, Paul

I think:

RCU_BH is not required, we can used RCU instead. so HAVE_SPECIAL_RCU_BH will help for implementation which has not RCU_BH.

HAVE_SPECIAL_RCU_SCHED is a little different, RCU and RCU_SCHED are both required for the kernel. But I think, in an implementation,
if rcu_read_lock_sched() implies rcu_read_lock(), we may not need implement RCU_SCHED too(sometimes we may implement RCU_SCHED for performance). so HAVE_SPECIAL_RCU_SCHED will help.

Thanx, Lai.

#4 lore raw
Quoted 26 lines · Lai Jiangshan
Quoted 18 lines · Paul E. McKenney
Quoted 5 lines · Lai Jiangshan

this fix remove ugly macro, and increase readability for rcupdate codes

changed from v1:
use HAVE_SPECIAL_RCU_BH/SCHED instead of define duplicate version of synchronize_sched().

Hello, Jiangshan!

I very much like getting rid of the ugly macro. I of course like the kernel-doc fixes. ;-)

I am not yet convinced of the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED pieces. It is not clear to me that this approach is simpler than the current approach of simply providing the appropriate definitions for the symbols in the implementation-specific rcuxxx.h file.

Quoted 4 lines

Am I missing something?

Thanx, Paul

I think:

Quoted 8 lines

RCU_BH is not required, we can used RCU instead. so HAVE_SPECIAL_RCU_BH will help for implementation which has not RCU_BH.

HAVE_SPECIAL_RCU_SCHED is a little different, RCU and RCU_SCHED are both required for the kernel. But I think, in an implementation,
if rcu_read_lock_sched() implies rcu_read_lock(), we may not need implement RCU_SCHED too(sometimes we may implement RCU_SCHED for performance). so HAVE_SPECIAL_RCU_SCHED will help.

If I understand correctly, this is the "old way":

------------------------------------------------------------------------

rcupdate.h:

#define rcu_read_lock_bh() __rcu_read_lock_bh() #define rcu_read_unlock_bh() __rcu_read_unlock_bh()

rcupreempt.h:

#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); }
#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); }

------------------------------------------------------------------------

And then this is the "new way":

------------------------------------------------------------------------

rcupdate.h:

#ifdef HAVE_SPECIAL_RCU_BH
#define rcu_read_lock_bh() __rcu_read_lock_bh()
#define rcu_read_unlock_bh() __rcu_read_unlock_bh()
#else
#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); }
#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); } #endif /* HAVE_SPECIAL_RCU_BH */

rcupreempt.h:

#define HAVE_SPECIAL_RCU_BH

------------------------------------------------------------------------

If we had ten different RCU implementations, then the "new way" would save a little bit of code. But the "old way" is a bit easier to figure out.

So I am in favor of getting rid of the ugly macro, and also in favor of fixing the kerneldoc, but opposed to the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED changes.

Or am I missing something?

Thanx, Paul

#5 lore raw
Quoted 68 lines · Paul E. McKenney
Quoted 24 lines · Lai Jiangshan
Quoted 17 lines · Paul E. McKenney
Quoted 5 lines · Lai Jiangshan

this fix remove ugly macro, and increase readability for rcupdate codes

changed from v1:
use HAVE_SPECIAL_RCU_BH/SCHED instead of define duplicate version of synchronize_sched().

Hello, Jiangshan!

I very much like getting rid of the ugly macro. I of course like the kernel-doc fixes. ;-)

I am not yet convinced of the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED pieces. It is not clear to me that this approach is simpler than the current approach of simply providing the appropriate definitions for the symbols in the implementation-specific rcuxxx.h file.

Quoted 4 lines

Am I missing something?

Thanx, Paul

I think:

Quoted 8 lines

RCU_BH is not required, we can used RCU instead. so HAVE_SPECIAL_RCU_BH will help for implementation which has not RCU_BH.

HAVE_SPECIAL_RCU_SCHED is a little different, RCU and RCU_SCHED are both required for the kernel. But I think, in an implementation,
if rcu_read_lock_sched() implies rcu_read_lock(), we may not need implement RCU_SCHED too(sometimes we may implement RCU_SCHED for performance). so HAVE_SPECIAL_RCU_SCHED will help.

If I understand correctly, this is the "old way":

------------------------------------------------------------------------

rcupdate.h:

#define rcu_read_lock_bh() __rcu_read_lock_bh() #define rcu_read_unlock_bh() __rcu_read_unlock_bh()

rcupreempt.h:

#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); }
#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); }

------------------------------------------------------------------------

And then this is the "new way":

------------------------------------------------------------------------

rcupdate.h:

#ifdef HAVE_SPECIAL_RCU_BH
#define rcu_read_lock_bh() __rcu_read_lock_bh()
#define rcu_read_unlock_bh() __rcu_read_unlock_bh()
#else
#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); }
#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); } #endif /* HAVE_SPECIAL_RCU_BH */

rcupreempt.h:

#define HAVE_SPECIAL_RCU_BH

Quoted 8 lines

------------------------------------------------------------------------

If we had ten different RCU implementations, then the "new way" would save a little bit of code. But the "old way" is a bit easier to figure out.

So I am in favor of getting rid of the ugly macro, and also in favor of fixing the kerneldoc, but opposed to the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED changes.

I apprehended and agree with you. Thanx.

Lai.

#6 lore raw
Quoted 71 lines · Lai Jiangshan
Quoted 70 lines · Paul E. McKenney
Quoted 24 lines · Lai Jiangshan
Quoted 17 lines · Paul E. McKenney
Quoted 5 lines · Lai Jiangshan

this fix remove ugly macro, and increase readability for rcupdate codes

changed from v1:
use HAVE_SPECIAL_RCU_BH/SCHED instead of define duplicate version of synchronize_sched().

Hello, Jiangshan!

I very much like getting rid of the ugly macro. I of course like the kernel-doc fixes. ;-)

I am not yet convinced of the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED pieces. It is not clear to me that this approach is simpler than the current approach of simply providing the appropriate definitions for the symbols in the implementation-specific rcuxxx.h file.

Quoted 4 lines

Am I missing something?

Thanx, Paul

I think:

Quoted 8 lines

RCU_BH is not required, we can used RCU instead. so HAVE_SPECIAL_RCU_BH will help for implementation which has not RCU_BH.

HAVE_SPECIAL_RCU_SCHED is a little different, RCU and RCU_SCHED are both required for the kernel. But I think, in an implementation,
if rcu_read_lock_sched() implies rcu_read_lock(), we may not need implement RCU_SCHED too(sometimes we may implement RCU_SCHED for performance). so HAVE_SPECIAL_RCU_SCHED will help.

If I understand correctly, this is the "old way":

------------------------------------------------------------------------

rcupdate.h:

#define rcu_read_lock_bh() __rcu_read_lock_bh() #define rcu_read_unlock_bh() __rcu_read_unlock_bh()

rcupreempt.h:

#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); }
#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); }

------------------------------------------------------------------------

And then this is the "new way":

------------------------------------------------------------------------

rcupdate.h:

#ifdef HAVE_SPECIAL_RCU_BH
#define rcu_read_lock_bh() __rcu_read_lock_bh()
#define rcu_read_unlock_bh() __rcu_read_unlock_bh()
#else
#define __rcu_read_lock_bh() { rcu_read_lock(); local_bh_disable(); }
#define __rcu_read_unlock_bh() { local_bh_enable(); rcu_read_unlock(); } #endif /* HAVE_SPECIAL_RCU_BH */

rcupreempt.h:

#define HAVE_SPECIAL_RCU_BH

------------------------------------------------------------------------

Quoted 8 lines
Quoted 6 lines

If we had ten different RCU implementations, then the "new way" would save a little bit of code. But the "old way" is a bit easier to figure out.

So I am in favor of getting rid of the ugly macro, and also in favor of fixing the kerneldoc, but opposed to the HAVE_SPECIAL_RCU_BH and HAVE_SPECIAL_RCU_SCHED changes.

I apprehended and agree with you. Thanx.

Sounds good -- and thank you for your much-needed efforts to improve the RCU implementation!

Thanx, Paul

#7 lore raw

Hi, Paul,

Could you add a RCU document about unloadable modules for kernel?

Thanx, Lai.

#8 lore raw
Quoted 4 lines · Lai Jiangshan

Hi, Paul,

Could you add a RCU document about unloadable modules for kernel?

You thinking in terms of an ASCII version of
http://lwn.net/Articles/217484/?

If so, please see attached patch and let me know what you think. Being too lazy to convert the cartoon to ASCII graphics, I simply left a URL to the .jpg on the LWN website. Thus we need an ack/nack from Jon Corbet (CCed).

Of course, an alternative is to simply include the URL of the original LWN article in 00-INDEX. Thoughts?

Thanx, Paul

---

 00-INDEX       |    2 
 rcubarrier.txt |  309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 311 insertions(+)
Documentation/RCU/00-INDEX +2 -0
diff -urpNa -X dontdiff linux-2.6.27/Documentation/RCU/00-INDEX linux-2.6.27-rcu_barrierdoc/Documentation/RCU/00-INDEX
@@ -12,6 +12,8 @@ rcuref.txt
 	- Reference-count design for elements of lists/arrays protected by RCU
 rcu.txt
 	- RCU Concepts
+rcubarrier.txt
+	- Unloading modules that use RCU callbacks
 RTFP.txt
 	- List of RCU papers (bibliography) going back to 1980.
 torture.txt
Documentation/RCU/rcubarrier.txt +309 -0

309 lines not on this page · raw message

#9 lore raw
Quoted 5 lines · Paul E. McKenney
Quoted 3 lines · Lai Jiangshan

Hi, Paul,

Could you add a RCU document about unloadable modules for kernel?

Quoted 7 lines

You thinking in terms of an ASCII version of
http://lwn.net/Articles/217484/?

If so, please see attached patch and let me know what you think. Being too lazy to convert the cartoon to ASCII graphics, I simply left a URL to the .jpg on the LWN website. Thus we need an ack/nack from Jon Corbet (CCed).

Hi, Paul

Thank you. it's a very good document.

I found several modules which need rcu_barrier(). So I'm going to do some cleanup for them. A document for rcu_barrier() will help these cleanup patches be accepted easily by maintainers.

Lai.

Quoted 13 lines

Of course, an alternative is to simply include the URL of the original LWN article in 00-INDEX. Thoughts?

Thanx, Paul

---

Documentation/RCU/rcubarrier.txt +4 -0
+The code for rcu_barrier() is as follows:
+
+ 1 void rcu_barrier(void)
+ 2 {

Documentation/RCU/rcubarrier.txt line 197

Quoted 10 lines
Documentation/RCU/rcubarrier.txt +10 -0
+ 3   BUG_ON(in_interrupt());
+ 4   /* Take cpucontrol mutex to protect against CPU hotplug */
+ 5   mutex_lock(&rcu_barrier_mutex);
+ 6   init_completion(&rcu_barrier_completion);
+ 7   atomic_set(&rcu_barrier_cpu_count, 0);
+ 8   on_each_cpu(rcu_barrier_func, NULL, 0, 1);
+ 9   wait_for_completion(&rcu_barrier_completion);
+10   mutex_unlock(&rcu_barrier_mutex);
+11 }
+

this is a little old.

Documentation/RCU/rcubarrier.txt line 264

Quoted 7 lines
Documentation/RCU/rcubarrier.txt +7 -0
+
+Quick Quiz #2: Why is there no rcu_barrier_bh()?
+
+Answer: Because no one has needed it yet. As soon as someone needs to
+	use call_rcu_bh() from within an unloadable module, they will
+	need an rcu_barrier_bh().
+

add here.

#10 lore raw
Quoted 9 lines · Lai Jiangshan
Quoted 8 lines · Paul E. McKenney
Quoted 3 lines · Lai Jiangshan

Hi, Paul,

Could you add a RCU document about unloadable modules for kernel?

You thinking in terms of an ASCII version of
http://lwn.net/Articles/217484/?

Quoted 8 lines
Quoted 4 lines

If so, please see attached patch and let me know what you think. Being too lazy to convert the cartoon to ASCII graphics, I simply left a URL to the .jpg on the LWN website. Thus we need an ack/nack from Jon Corbet (CCed).

Hi, Paul

Thank you. it's a very good document.

Updated version attached.

Quoted 3 lines

I found several modules which need rcu_barrier(). So I'm going to do some cleanup for them. A document for rcu_barrier() will help these cleanup patches be accepted easily by maintainers.

Sounds very good!!!

Quoted 11 lines

Lai.

Quoted 8 lines

Of course, an alternative is to simply include the URL of the original LWN article in 00-INDEX. Thoughts?

Thanx, Paul

---

Quoted 16 lines
Quoted 4 lines
(quoted diff) +4 -0
+The code for rcu_barrier() is as follows:
+
+ 1 void rcu_barrier(void)
+ 2 {

Review

Quoted 10 lines
(quoted diff) +10 -0
+ 3   BUG_ON(in_interrupt());
+ 4   /* Take cpucontrol mutex to protect against CPU hotplug */
+ 5   mutex_lock(&rcu_barrier_mutex);
+ 6   init_completion(&rcu_barrier_completion);
+ 7   atomic_set(&rcu_barrier_cpu_count, 0);
+ 8   on_each_cpu(rcu_barrier_func, NULL, 0, 1);
+ 9   wait_for_completion(&rcu_barrier_completion);
+10   mutex_unlock(&rcu_barrier_mutex);
+11 }
+

this is a little old.

Indeed!!! Good catch! I left this code, but added words saying that it was the original and that it has since been rewritten to add support for rcu_barrier_bh() and rcu_barrier_sched().

Quoted 9 lines

Review

Quoted 7 lines
(quoted diff) +7 -0
+
+Quick Quiz #2: Why is there no rcu_barrier_bh()?
+
+Answer: Because no one has needed it yet. As soon as someone needs to
+	use call_rcu_bh() from within an unloadable module, they will
+	need an rcu_barrier_bh().
+

add here.

Good point, I deleted this Quick Quiz.

---

Documentation/RCU/00-INDEX +2 -0
diff -urpNa -X dontdiff linux-2.6.27/Documentation/RCU/00-INDEX linux-2.6.27-rcu_barrierdoc/Documentation/RCU/00-INDEX
@@ -12,6 +12,8 @@ rcuref.txt
 	- Reference-count design for elements of lists/arrays protected by RCU
 rcu.txt
 	- RCU Concepts
+rcubarrier.txt
+	- Unloading modules that use RCU callbacks
 RTFP.txt
 	- List of RCU papers (bibliography) going back to 1980.
 torture.txt
Documentation/RCU/rcubarrier.txt +304 -0

304 lines not on this page · raw message

author Reviewed-by
#11 lore raw

Paul E. McKenney wrote:
[...]

Quoted 18 lines

---

diff -urpNa -X dontdiff linux-2.6.27/Documentation/RCU/00-INDEX linux-2.6.27-rcu_barrierdoc/Documentation/RCU/00-INDEX

Documentation/RCU/00-INDEX +2 -0
@@ -12,6 +12,8 @@ rcuref.txt
 	- Reference-count design for elements of lists/arrays protected by RCU
 rcu.txt
 	- RCU Concepts
+rcubarrier.txt
+	- Unloading modules that use RCU callbacks
 RTFP.txt
 	- List of RCU papers (bibliography) going back to 1980.
 torture.txt

diff -urpNa -X dontdiff linux-2.6.27/Documentation/RCU/rcubarrier.txt linux-2.6.27-rcu_barrierdoc/Documentation/RCU/rcubarrier.txt

Documentation/RCU/rcubarrier.txt +0 -0

[...]

maintainer
#12 lore raw
Quoted 3 lines · On Fri, 14 Nov 2008 15:39:02 +0800 Lai Jiangshan <[email protected]> wrote:

Paul E. McKenney wrote:

All seems good. To answer Paul's original question:

Quoted 4 lines

If so, please see attached patch and let me know what you think. Being too lazy to convert the cartoon to ASCII graphics, I simply left a URL to the .jpg on the LWN website. Thus we need an ack/nack from Jon Corbet (CCed).

Of course I have no problem with the LWN links; they will remain stable.

If nobody objects, I'll drop this into my documentation tree. Gotta have *something* there, after all, or it might start to feel neglected...

jon

#13 lore raw
Quoted 14 lines · Jonathan Corbet
Quoted 3 lines · On Fri, 14 Nov 2008 15:39:02 +0800 Lai Jiangshan <[email protected]> wrote:

Paul E. McKenney wrote:

All seems good. To answer Paul's original question:

Quoted 4 lines

If so, please see attached patch and let me know what you think. Being too lazy to convert the cartoon to ASCII graphics, I simply left a URL to the .jpg on the LWN website. Thus we need an ack/nack from Jon Corbet (CCed).

Quoted 5 lines

Of course I have no problem with the LWN links; they will remain stable.

If nobody objects, I'll drop this into my documentation tree. Gotta have *something* there, after all, or it might start to feel neglected...

Works for me!

Thanx, Paul

#14 lore raw

Hi, Ingo,

Is there any problem for this document added to kernel?

Thanx, Lai.

Quoted 25 lines · Paul E. McKenney
Quoted 12 lines · Jonathan Corbet
Quoted 3 lines · On Fri, 14 Nov 2008 15:39:02 +0800 Lai Jiangshan <[email protected]> wrote:

Paul E. McKenney wrote:

All seems good. To answer Paul's original question:

Quoted 4 lines

If so, please see attached patch and let me know what you think. Being too lazy to convert the cartoon to ASCII graphics, I simply left a URL to the .jpg on the LWN website. Thus we need an ack/nack from Jon Corbet (CCed).

Quoted 5 lines

Of course I have no problem with the LWN links; they will remain stable.

If nobody objects, I'll drop this into my documentation tree. Gotta have *something* there, after all, or it might start to feel neglected...

Works for me!

Thanx, Paul

maintainer
#15 lore raw
Quoted 1 line · On Mon, 17 Nov 2008 20:57:40 +0800 Lai Jiangshan <[email protected]> wrote:

Is there any problem for this document added to kernel?

No problem; I'll get it queued up for 2.6.29 unless somebody else gets it there first.

jon