diff options
Diffstat (limited to 'kernel/rcu/rcu.h')
-rw-r--r-- | kernel/rcu/rcu.h | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/kernel/rcu/rcu.h b/kernel/rcu/rcu.h index 7859a0a3951e..79c3877e9c5b 100644 --- a/kernel/rcu/rcu.h +++ b/kernel/rcu/rcu.h | |||
@@ -96,19 +96,22 @@ static inline void debug_rcu_head_unqueue(struct rcu_head *head) | |||
96 | } | 96 | } |
97 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ | 97 | #endif /* #else !CONFIG_DEBUG_OBJECTS_RCU_HEAD */ |
98 | 98 | ||
99 | extern void kfree(const void *); | 99 | void kfree(const void *); |
100 | 100 | ||
101 | static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head) | 101 | static inline bool __rcu_reclaim(const char *rn, struct rcu_head *head) |
102 | { | 102 | { |
103 | unsigned long offset = (unsigned long)head->func; | 103 | unsigned long offset = (unsigned long)head->func; |
104 | 104 | ||
105 | rcu_lock_acquire(&rcu_callback_map); | ||
105 | if (__is_kfree_rcu_offset(offset)) { | 106 | if (__is_kfree_rcu_offset(offset)) { |
106 | RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset)); | 107 | RCU_TRACE(trace_rcu_invoke_kfree_callback(rn, head, offset)); |
107 | kfree((void *)head - offset); | 108 | kfree((void *)head - offset); |
109 | rcu_lock_release(&rcu_callback_map); | ||
108 | return 1; | 110 | return 1; |
109 | } else { | 111 | } else { |
110 | RCU_TRACE(trace_rcu_invoke_callback(rn, head)); | 112 | RCU_TRACE(trace_rcu_invoke_callback(rn, head)); |
111 | head->func(head); | 113 | head->func(head); |
114 | rcu_lock_release(&rcu_callback_map); | ||
112 | return 0; | 115 | return 0; |
113 | } | 116 | } |
114 | } | 117 | } |