[<prev] [next>] [day] [month] [year] [list]
Message-ID: <159618739523.4006.6314340287723253932.tip-bot2@tip-bot2>
Date: Fri, 31 Jul 2020 09:23:15 -0000
From: "tip-bot2 for Uladzislau Rezki (Sony)" <tip-bot2@...utronix.de>
To: linux-tip-commits@...r.kernel.org
Cc: "Joel Fernandes (Google)" <joel@...lfernandes.org>,
"Uladzislau Rezki (Sony)" <urezki@...il.com>,
"Paul E. McKenney" <paulmck@...nel.org>, x86 <x86@...nel.org>,
LKML <linux-kernel@...r.kernel.org>
Subject: [tip: core/rcu] rcu: Introduce single argument kvfree_rcu() interface
The following commit has been merged into the core/rcu branch of tip:
Commit-ID: 1835f475e3518ade61e25a57572c78b953778656
Gitweb: https://git.kernel.org/tip/1835f475e3518ade61e25a57572c78b953778656
Author: Uladzislau Rezki (Sony) <urezki@...il.com>
AuthorDate: Mon, 25 May 2020 23:47:59 +02:00
Committer: Paul E. McKenney <paulmck@...nel.org>
CommitterDate: Mon, 29 Jun 2020 11:59:26 -07:00
rcu: Introduce single argument kvfree_rcu() interface
Make kvfree_rcu() capable of freeing objects that will not
embed an rcu_head within it. This saves storage overhead in
such objects. Reclaiming headless objects this way requires
only a single argument (pointer to the object).
After this patch, there are two ways to use kvfree_rcu():
a) kvfree_rcu(ptr, rhf);
struct X {
struct rcu_head rhf;
unsigned char data[100];
};
void *ptr = kvmalloc(sizeof(struct X), GFP_KERNEL);
if (ptr)
kvfree_rcu(ptr, rhf);
b) kvfree_rcu(ptr);
void *ptr = kvmalloc(some_bytes, GFP_KERNEL);
if (ptr)
kvfree_rcu(ptr);
Note that the headless usage (example b) can only be used in a code
that can sleep. This is enforced by the CONFIG_DEBUG_ATOMIC_SLEEP
option.
Co-developed-by: Joel Fernandes (Google) <joel@...lfernandes.org>
Reviewed-by: Joel Fernandes (Google) <joel@...lfernandes.org>
Signed-off-by: Uladzislau Rezki (Sony) <urezki@...il.com>
Signed-off-by: Paul E. McKenney <paulmck@...nel.org>
---
include/linux/rcupdate.h | 38 ++++++++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 51b26ab..d15d46d 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -877,12 +877,42 @@ do { \
/**
* kvfree_rcu() - kvfree an object after a grace period.
- * @ptr: pointer to kvfree
- * @rhf: the name of the struct rcu_head within the type of @ptr.
*
- * Same as kfree_rcu(), just simple alias.
+ * This macro consists of one or two arguments and it is
+ * based on whether an object is head-less or not. If it
+ * has a head then a semantic stays the same as it used
+ * to be before:
+ *
+ * kvfree_rcu(ptr, rhf);
+ *
+ * where @ptr is a pointer to kvfree(), @rhf is the name
+ * of the rcu_head structure within the type of @ptr.
+ *
+ * When it comes to head-less variant, only one argument
+ * is passed and that is just a pointer which has to be
+ * freed after a grace period. Therefore the semantic is
+ *
+ * kvfree_rcu(ptr);
+ *
+ * where @ptr is a pointer to kvfree().
+ *
+ * Please note, head-less way of freeing is permitted to
+ * use from a context that has to follow might_sleep()
+ * annotation. Otherwise, please switch and embed the
+ * rcu_head structure within the type of @ptr.
*/
-#define kvfree_rcu(ptr, rhf) kfree_rcu(ptr, rhf)
+#define kvfree_rcu(...) KVFREE_GET_MACRO(__VA_ARGS__, \
+ kvfree_rcu_arg_2, kvfree_rcu_arg_1)(__VA_ARGS__)
+
+#define KVFREE_GET_MACRO(_1, _2, NAME, ...) NAME
+#define kvfree_rcu_arg_2(ptr, rhf) kfree_rcu(ptr, rhf)
+#define kvfree_rcu_arg_1(ptr) \
+do { \
+ typeof(ptr) ___p = (ptr); \
+ \
+ if (___p) \
+ kvfree_call_rcu(NULL, (rcu_callback_t) (___p)); \
+} while (0)
/*
* Place this after a lock-acquisition primitive to guarantee that
Powered by blists - more mailing lists