[PATCH] rcu: Replace kfree() with kvfree() as callback for kfree_rcu()
From: Kirill Tkhai
Date: Thu Feb 13 2020 - 07:01:41 EST
Like Paul suggested, we start from simple replacing kfree()
with kvfree() in kfree_rcu() callbacks:
https://www.spinics.net/lists/kernel/msg2729683.html
kvfree() works both with kmalloc()'ed and vmalloc()'ed memory,
so we use it to free both of them via kfree_rcu().
Signed-off-by: Kirill Tkhai <ktkhai@xxxxxxxxxxxxx>
---
include/linux/rcupdate.h | 2 ++
kernel/rcu/tiny.c | 2 +-
kernel/rcu/tree.c | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 2678a37c3169..0a42c443c203 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -842,6 +842,8 @@ do { \
__kfree_rcu(&((___p)->rhf), offsetof(typeof(*(ptr)), rhf)); \
} while (0)
+#define kvfree_rcu(ptr, rhf) kfree_rcu(ptr, rhf)
+
/*
* Place this after a lock-acquisition primitive to guarantee that
* an UNLOCK+LOCK pair acts as a full barrier. This guarantee applies
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
index dd572ce7c747..16930c8f5749 100644
--- a/kernel/rcu/tiny.c
+++ b/kernel/rcu/tiny.c
@@ -86,7 +86,7 @@ static inline bool rcu_reclaim_tiny(struct rcu_head *head)
rcu_lock_acquire(&rcu_callback_map);
if (__is_kfree_rcu_offset(offset)) {
trace_rcu_invoke_kfree_callback("", head, offset);
- kfree((void *)head - offset);
+ kvfree((void *)head - offset);
rcu_lock_release(&rcu_callback_map);
return true;
}
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 16fd113796a7..cbe809bf6f4a 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -2879,7 +2879,7 @@ static void kfree_rcu_work(struct work_struct *work)
trace_rcu_invoke_kfree_callback(rcu_state.name, head, offset);
if (!WARN_ON_ONCE(!__is_kfree_rcu_offset(offset)))
- kfree((void *)head - offset);
+ kvfree((void *)head - offset);
rcu_lock_release(&rcu_callback_map);
cond_resched_tasks_rcu_qs();