Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

slab, rcu: move TINY_RCU variant of kvfree_rcu() to SLAB

Following the move of TREE_RCU implementation, let's move also the
TINY_RCU one for consistency and subsequent refactoring.

For simplicity, remove the separate inline __kvfree_call_rcu() as
TINY_RCU is not meant for high-performance hardware anyway.

Declare kvfree_call_rcu() in rcupdate.h to avoid header dependency
issues.

Also move the kvfree_rcu_barrier() declaration to slab.h

Reviewed-by: Uladzislau Rezki (Sony) <urezki@gmail.com>
Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
Tested-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>

+38 -50
+5
include/linux/rcupdate.h
··· 1082 1082 #define kfree_rcu_mightsleep(ptr) kvfree_rcu_arg_1(ptr) 1083 1083 #define kvfree_rcu_mightsleep(ptr) kvfree_rcu_arg_1(ptr) 1084 1084 1085 + /* 1086 + * In mm/slab_common.c, no suitable header to include here. 1087 + */ 1088 + void kvfree_call_rcu(struct rcu_head *head, void *ptr); 1089 + 1085 1090 #define kvfree_rcu_arg_2(ptr, rhf) \ 1086 1091 do { \ 1087 1092 typeof (ptr) ___p = (ptr); \
-36
include/linux/rcutiny.h
··· 90 90 synchronize_rcu(); 91 91 } 92 92 93 - /* 94 - * Add one more declaration of kvfree() here. It is 95 - * not so straight forward to just include <linux/mm.h> 96 - * where it is defined due to getting many compile 97 - * errors caused by that include. 98 - */ 99 - extern void kvfree(const void *addr); 100 - 101 - static inline void __kvfree_call_rcu(struct rcu_head *head, void *ptr) 102 - { 103 - if (head) { 104 - call_rcu(head, (rcu_callback_t) ((void *) head - ptr)); 105 - return; 106 - } 107 - 108 - // kvfree_rcu(one_arg) call. 109 - might_sleep(); 110 - synchronize_rcu(); 111 - kvfree(ptr); 112 - } 113 - 114 - static inline void kvfree_rcu_barrier(void) 115 - { 116 - rcu_barrier(); 117 - } 118 - 119 - #ifdef CONFIG_KASAN_GENERIC 120 - void kvfree_call_rcu(struct rcu_head *head, void *ptr); 121 - #else 122 - static inline void kvfree_call_rcu(struct rcu_head *head, void *ptr) 123 - { 124 - __kvfree_call_rcu(head, ptr); 125 - } 126 - #endif 127 - 128 93 void rcu_qs(void); 129 94 130 95 static inline void rcu_softirq_qs(void) ··· 129 164 static inline bool rcu_inkernel_boot_has_ended(void) { return true; } 130 165 static inline bool rcu_is_watching(void) { return true; } 131 166 static inline void rcu_momentary_eqs(void) { } 132 - static inline void kfree_rcu_scheduler_running(void) { } 133 167 134 168 /* Avoid RCU read-side critical sections leaking across. */ 135 169 static inline void rcu_all_qs(void) { barrier(); }
-3
include/linux/rcutree.h
··· 34 34 } 35 35 36 36 void synchronize_rcu_expedited(void); 37 - void kvfree_call_rcu(struct rcu_head *head, void *ptr); 38 - void kvfree_rcu_barrier(void); 39 37 40 38 void rcu_barrier(void); 41 39 void rcu_momentary_eqs(void); 42 - void kfree_rcu_scheduler_running(void); 43 40 44 41 struct rcu_gp_oldstate { 45 42 unsigned long rgos_norm;
+14
include/linux/slab.h
··· 16 16 #include <linux/gfp.h> 17 17 #include <linux/overflow.h> 18 18 #include <linux/types.h> 19 + #include <linux/rcupdate.h> 19 20 #include <linux/workqueue.h> 20 21 #include <linux/percpu-refcount.h> 21 22 #include <linux/cleanup.h> ··· 1082 1081 extern void kvfree_sensitive(const void *addr, size_t len); 1083 1082 1084 1083 unsigned int kmem_cache_size(struct kmem_cache *s); 1084 + 1085 + #ifdef CONFIG_TINY_RCU 1086 + static inline void kvfree_rcu_barrier(void) 1087 + { 1088 + rcu_barrier(); 1089 + } 1090 + 1091 + static inline void kfree_rcu_scheduler_running(void) { } 1092 + #else 1093 + void kvfree_rcu_barrier(void); 1094 + 1095 + void kfree_rcu_scheduler_running(void); 1096 + #endif 1085 1097 1086 1098 /** 1087 1099 * kmalloc_size_roundup - Report allocation bucket size for the given size
-11
kernel/rcu/tiny.c
··· 246 246 } 247 247 EXPORT_SYMBOL_GPL(poll_state_synchronize_rcu); 248 248 249 - #ifdef CONFIG_KASAN_GENERIC 250 - void kvfree_call_rcu(struct rcu_head *head, void *ptr) 251 - { 252 - if (head) 253 - kasan_record_aux_stack(ptr); 254 - 255 - __kvfree_call_rcu(head, ptr); 256 - } 257 - EXPORT_SYMBOL_GPL(kvfree_call_rcu); 258 - #endif 259 - 260 249 void __init rcu_init(void) 261 250 { 262 251 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+19
mm/slab_common.c
··· 1284 1284 EXPORT_TRACEPOINT_SYMBOL(kfree); 1285 1285 EXPORT_TRACEPOINT_SYMBOL(kmem_cache_free); 1286 1286 1287 + #ifdef CONFIG_TINY_RCU 1288 + 1289 + void kvfree_call_rcu(struct rcu_head *head, void *ptr) 1290 + { 1291 + if (head) { 1292 + kasan_record_aux_stack(ptr); 1293 + call_rcu(head, (rcu_callback_t) ((void *) head - ptr)); 1294 + return; 1295 + } 1296 + 1297 + // kvfree_rcu(one_arg) call. 1298 + might_sleep(); 1299 + synchronize_rcu(); 1300 + kvfree(ptr); 1301 + } 1302 + EXPORT_SYMBOL_GPL(kvfree_call_rcu); 1303 + 1304 + #endif 1305 + 1287 1306 /* 1288 1307 * This rcu parameter is runtime-read-only. It reflects 1289 1308 * a minimum allowed number of objects which can be cached