|
@@ -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))
|