diff mbox

[RFC,tip/core/rcu,5/6] rcu: Make __kfree_rcu() less dependent on compiler choices

Message ID 1335199347-13926-5-git-send-email-paulmck@linux.vnet.ibm.com
State Accepted
Commit d8169d4c369e8aa2fda10df705a4957331b5a4db
Headers show

Commit Message

Paul E. McKenney April 23, 2012, 4:42 p.m. UTC
From: Jan Engelhardt <jengelh@medozas.de>

Currently, __kfree_rcu() is implemented as an inline function, and
contains a BUILD_BUG_ON() that malfunctions if __kfree_rcu() is compiled
as an out-of-line function.  Unfortunately, there are compiler settings
(e.g., -O0) that can result in __kfree_rcu() being compiled out of line,
resulting in annoying build breakage.  This commit therefore converts
both __kfree_rcu() and __is_kfree_rcu_offset() from inline functions to
macros to prevent such misbehavior on the part of the compiler.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
---
 include/linux/rcupdate.h |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

Comments

Peter Zijlstra April 26, 2012, 12:48 p.m. UTC | #1
On Mon, 2012-04-23 at 09:42 -0700, Paul E. McKenney wrote:
> Currently, __kfree_rcu() is implemented as an inline function, and
> contains a BUILD_BUG_ON() that malfunctions if __kfree_rcu() is compiled
> as an out-of-line function.  Unfortunately, there are compiler settings
> (e.g., -O0) that can result in __kfree_rcu() being compiled out of line,
> resulting in annoying build breakage.  This commit therefore converts
> both __kfree_rcu() and __is_kfree_rcu_offset() from inline functions to
> macros to prevent such misbehavior on the part of the compiler.

The kernel very explicitly doesn't support being compiled with -O0, so
this is a non-issue, I think you can make it work if you add
-finline-functions.

I'd drop this, either make the entire kernel compile or don't bother.
Jan Engelhardt April 26, 2012, 1:29 p.m. UTC | #2
On Thursday 2012-04-26 14:48, Peter Zijlstra wrote:
>On Mon, 2012-04-23 at 09:42 -0700, Paul E. McKenney wrote:
>> Currently, __kfree_rcu() is implemented as an inline function, and
>> contains a BUILD_BUG_ON() that malfunctions if __kfree_rcu() is compiled
>> as an out-of-line function.  Unfortunately, there are compiler settings
>> (e.g., -O0) that can result in __kfree_rcu() being compiled out of line,
>> resulting in annoying build breakage.  This commit therefore converts
>> both __kfree_rcu() and __is_kfree_rcu_offset() from inline functions to
>> macros to prevent such misbehavior on the part of the compiler.
>
>The kernel very explicitly doesn't support being compiled with -O0, so
>this is a non-issue, I think you can make it work if you add
>-finline-functions.
>
>I'd drop this, either make the entire kernel compile or don't bother.

It was not originally meant to make the entire kernel compile with -O0,
but only select modules/.c files.
That, or __always_inline just does not always inline.
Peter Zijlstra April 26, 2012, 1:50 p.m. UTC | #3
On Thu, 2012-04-26 at 15:29 +0200, Jan Engelhardt wrote:
> On Thursday 2012-04-26 14:48, Peter Zijlstra wrote:
> >On Mon, 2012-04-23 at 09:42 -0700, Paul E. McKenney wrote:
> >> Currently, __kfree_rcu() is implemented as an inline function, and
> >> contains a BUILD_BUG_ON() that malfunctions if __kfree_rcu() is compiled
> >> as an out-of-line function.  Unfortunately, there are compiler settings
> >> (e.g., -O0) that can result in __kfree_rcu() being compiled out of line,
> >> resulting in annoying build breakage.  This commit therefore converts
> >> both __kfree_rcu() and __is_kfree_rcu_offset() from inline functions to
> >> macros to prevent such misbehavior on the part of the compiler.
> >
> >The kernel very explicitly doesn't support being compiled with -O0, so
> >this is a non-issue, I think you can make it work if you add
> >-finline-functions.
> >
> >I'd drop this, either make the entire kernel compile or don't bother.
> 
> It was not originally meant to make the entire kernel compile with -O0,
> but only select modules/.c files.

Same problem, who cares about select modules/.c files? Why should they
have different rules?

> That, or __always_inline just does not always inline.

It does indeed not without -finline-functions.
diff mbox

Patch

diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 20fb776..d5dfb10 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -922,6 +922,21 @@  void __kfree_rcu(struct rcu_head *head, unsigned long offset)
 	kfree_call_rcu(head, (rcu_callback)offset);
 }
 
+/*
+ * Does the specified offset indicate that the corresponding rcu_head
+ * structure can be handled by kfree_rcu()?
+ */
+#define __is_kfree_rcu_offset(offset) ((offset) < 4096)
+
+/*
+ * Helper macro for kfree_rcu() to prevent argument-expansion eyestrain.
+ */
+#define __kfree_rcu(head, offset) \
+	do { \
+		BUILD_BUG_ON(!__is_kfree_rcu_offset(offset)); \
+		call_rcu(head, (void (*)(struct rcu_head *))(unsigned long)(offset)); \
+	} while (0)
+
 /**
  * kfree_rcu() - kfree an object after a grace period.
  * @ptr:	pointer to kfree
@@ -944,6 +959,9 @@  void __kfree_rcu(struct rcu_head *head, unsigned long offset)
  *
  * Note that the allowable offset might decrease in the future, for example,
  * to allow something like kmem_cache_free_rcu().
+ *
+ * The BUILD_BUG_ON check must not involve any function calls, hence the
+ * checks are done in macros here.
  */
 #define kfree_rcu(ptr, rcu_head)					\
 	__kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))