diff options
author | Paul E. McKenney <paul.mckenney@linaro.org> | 2011-06-17 18:53:19 -0400 |
---|---|---|
committer | Paul E. McKenney <paulmck@linux.vnet.ibm.com> | 2011-09-29 00:38:12 -0400 |
commit | 29c00b4a1d9e277786120032aa8364631820d863 (patch) | |
tree | 23bf0c8cdb5268ef92ef9ed007639705e922b1b0 /include/linux/rcupdate.h | |
parent | 9d68197c05201d8edc70d58bd1d5dad05d8455e8 (diff) |
rcu: Add event-tracing for RCU callback invocation
There was recently some controversy about the overhead of invoking RCU
callbacks. Add TRACE_EVENT()s to obtain fine-grained timings for the
start and stop of a batch of callbacks and also for each callback invoked.
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Diffstat (limited to 'include/linux/rcupdate.h')
-rw-r--r-- | include/linux/rcupdate.h | 50 |
1 files changed, 0 insertions, 50 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index ae5327de41a..dd2bc2c6a28 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -794,44 +794,6 @@ static inline notrace void rcu_read_unlock_sched_notrace(void) | |||
794 | #define RCU_INIT_POINTER(p, v) \ | 794 | #define RCU_INIT_POINTER(p, v) \ |
795 | p = (typeof(*v) __force __rcu *)(v) | 795 | p = (typeof(*v) __force __rcu *)(v) |
796 | 796 | ||
797 | /* | ||
798 | * debug_rcu_head_queue()/debug_rcu_head_unqueue() are used internally | ||
799 | * by call_rcu() and rcu callback execution, and are therefore not part of the | ||
800 | * RCU API. Leaving in rcupdate.h because they are used by all RCU flavors. | ||
801 | */ | ||
802 | |||
803 | #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD | ||
804 | # define STATE_RCU_HEAD_READY 0 | ||
805 | # define STATE_RCU_HEAD_QUEUED 1 | ||
806 | |||
807 | extern struct debug_obj_descr rcuhead_debug_descr; | ||
808 | |||
809 | static inline void debug_rcu_head_queue(struct rcu_head *head) | ||
810 | { | ||
811 | WARN_ON_ONCE((unsigned long)head & 0x3); | ||
812 | debug_object_activate(head, &rcuhead_debug_descr); | ||
813 | debug_object_active_state(head, &rcuhead_debug_descr, | ||
814 | STATE_RCU_HEAD_READY, | ||
815 | STATE_RCU_HEAD_QUEUED); | ||
816 | } | ||
817 | |||
818 | static inline void debug_rcu_head_unqueue(struct rcu_head *head) | ||
819 | { | ||
820 | debug_object_active_state(head, &rcuhead_debug_descr, | ||
821 | STATE_RCU_HEAD_QUEUED, | ||
822 | STATE_RCU_HEAD_READY); | ||
823 | debug_object_deactivate(head, &rcuhead_debug_descr); | ||
824 | } | ||
825 | #else /* !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
826 | static inline void debug_rcu_head_queue(struct rcu_head *head) | ||
827 | { | ||
828 | } | ||
829 | |||
830 | static inline void debug_rcu_head_unqueue(struct rcu_head *head) | ||
831 | { | ||
832 | } | ||
833 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | ||
834 | |||
835 | static __always_inline bool __is_kfree_rcu_offset(unsigned long offset) | 797 | static __always_inline bool __is_kfree_rcu_offset(unsigned long offset) |
836 | { | 798 | { |
837 | return offset < 4096; | 799 | return offset < 4096; |
@@ -850,18 +812,6 @@ void __kfree_rcu(struct rcu_head *head, unsigned long offset) | |||
850 | call_rcu(head, (rcu_callback)offset); | 812 | call_rcu(head, (rcu_callback)offset); |
851 | } | 813 | } |
852 | 814 | ||
853 | extern void kfree(const void *); | ||
854 | |||
855 | static inline void __rcu_reclaim(struct rcu_head *head) | ||
856 | { | ||
857 | unsigned long offset = (unsigned long)head->func; | ||
858 | |||
859 | if (__is_kfree_rcu_offset(offset)) | ||
860 | kfree((void *)head - offset); | ||
861 | else | ||
862 | head->func(head); | ||
863 | } | ||
864 | |||
865 | /** | 815 | /** |
866 | * kfree_rcu() - kfree an object after a grace period. | 816 | * kfree_rcu() - kfree an object after a grace period. |
867 | * @ptr: pointer to kfree | 817 | * @ptr: pointer to kfree |