Skip to content

Commit 04a522b

Browse files
urezkipaulmckrcu
authored andcommitted
rcu: Refactor kvfree_call_rcu() and high-level helpers
Currently a kvfree_call_rcu() takes an offset within a structure as a second parameter, so a helper such as a kvfree_rcu_arg_2() has to convert rcu_head and a freed ptr to an offset in order to pass it. That leads to an extra conversion on macro entry. Instead of converting, refactor the code in way that a pointer that has to be freed is passed directly to the kvfree_call_rcu(). This patch does not make any functional change and is transparent to all kvfree_rcu() users. Signed-off-by: Uladzislau Rezki (Sony) <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 1b929c0 commit 04a522b

File tree

5 files changed

+24
-33
lines changed

5 files changed

+24
-33
lines changed

include/linux/rcupdate.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,8 +1011,7 @@ do { \
10111011
\
10121012
if (___p) { \
10131013
BUILD_BUG_ON(!__is_kvfree_rcu_offset(offsetof(typeof(*(ptr)), rhf))); \
1014-
kvfree_call_rcu(&((___p)->rhf), (rcu_callback_t)(unsigned long) \
1015-
(offsetof(typeof(*(ptr)), rhf))); \
1014+
kvfree_call_rcu(&((___p)->rhf), (void *) (___p)); \
10161015
} \
10171016
} while (0)
10181017

@@ -1021,7 +1020,7 @@ do { \
10211020
typeof(ptr) ___p = (ptr); \
10221021
\
10231022
if (___p) \
1024-
kvfree_call_rcu(NULL, (rcu_callback_t) (___p)); \
1023+
kvfree_call_rcu(NULL, (void *) (___p)); \
10251024
} while (0)
10261025

10271026
/*

include/linux/rcutiny.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,25 +98,25 @@ static inline void synchronize_rcu_expedited(void)
9898
*/
9999
extern void kvfree(const void *addr);
100100

101-
static inline void __kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
101+
static inline void __kvfree_call_rcu(struct rcu_head *head, void *ptr)
102102
{
103103
if (head) {
104-
call_rcu(head, func);
104+
call_rcu(head, (rcu_callback_t) ((void *) head - ptr));
105105
return;
106106
}
107107

108108
// kvfree_rcu(one_arg) call.
109109
might_sleep();
110110
synchronize_rcu();
111-
kvfree((void *) func);
111+
kvfree(ptr);
112112
}
113113

114114
#ifdef CONFIG_KASAN_GENERIC
115-
void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func);
115+
void kvfree_call_rcu(struct rcu_head *head, void *ptr);
116116
#else
117-
static inline void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
117+
static inline void kvfree_call_rcu(struct rcu_head *head, void *ptr)
118118
{
119-
__kvfree_call_rcu(head, func);
119+
__kvfree_call_rcu(head, ptr);
120120
}
121121
#endif
122122

include/linux/rcutree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static inline void rcu_virt_note_context_switch(void)
3333
}
3434

3535
void synchronize_rcu_expedited(void);
36-
void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func);
36+
void kvfree_call_rcu(struct rcu_head *head, void *ptr);
3737

3838
void rcu_barrier(void);
3939
bool rcu_eqs_special_set(int cpu);

kernel/rcu/tiny.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,12 @@ bool poll_state_synchronize_rcu(unsigned long oldstate)
246246
EXPORT_SYMBOL_GPL(poll_state_synchronize_rcu);
247247

248248
#ifdef CONFIG_KASAN_GENERIC
249-
void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
249+
void kvfree_call_rcu(struct rcu_head *head, void *ptr)
250250
{
251-
if (head) {
252-
void *ptr = (void *) head - (unsigned long) func;
253-
251+
if (head)
254252
kasan_record_aux_stack_noalloc(ptr);
255-
}
256253

257-
__kvfree_call_rcu(head, func);
254+
__kvfree_call_rcu(head, ptr);
258255
}
259256
EXPORT_SYMBOL_GPL(kvfree_call_rcu);
260257
#endif

kernel/rcu/tree.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,8 +3103,8 @@ static void kfree_rcu_work(struct work_struct *work)
31033103
* This list is named "Channel 3".
31043104
*/
31053105
for (; head; head = next) {
3106-
unsigned long offset = (unsigned long)head->func;
3107-
void *ptr = (void *)head - offset;
3106+
void *ptr = (void *) head->func;
3107+
unsigned long offset = (void *) head - ptr;
31083108

31093109
next = head->next;
31103110
debug_rcu_head_unqueue((struct rcu_head *)ptr);
@@ -3342,26 +3342,21 @@ add_ptr_to_bulk_krc_lock(struct kfree_rcu_cpu **krcp,
33423342
* be free'd in workqueue context. This allows us to: batch requests together to
33433343
* reduce the number of grace periods during heavy kfree_rcu()/kvfree_rcu() load.
33443344
*/
3345-
void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
3345+
void kvfree_call_rcu(struct rcu_head *head, void *ptr)
33463346
{
33473347
unsigned long flags;
33483348
struct kfree_rcu_cpu *krcp;
33493349
bool success;
3350-
void *ptr;
33513350

3352-
if (head) {
3353-
ptr = (void *) head - (unsigned long) func;
3354-
} else {
3355-
/*
3356-
* Please note there is a limitation for the head-less
3357-
* variant, that is why there is a clear rule for such
3358-
* objects: it can be used from might_sleep() context
3359-
* only. For other places please embed an rcu_head to
3360-
* your data.
3361-
*/
3351+
/*
3352+
* Please note there is a limitation for the head-less
3353+
* variant, that is why there is a clear rule for such
3354+
* objects: it can be used from might_sleep() context
3355+
* only. For other places please embed an rcu_head to
3356+
* your data.
3357+
*/
3358+
if (!head)
33623359
might_sleep();
3363-
ptr = (unsigned long *) func;
3364-
}
33653360

33663361
// Queue the object but don't yet schedule the batch.
33673362
if (debug_rcu_head_queue(ptr)) {
@@ -3382,7 +3377,7 @@ void kvfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
33823377
// Inline if kvfree_rcu(one_arg) call.
33833378
goto unlock_return;
33843379

3385-
head->func = func;
3380+
head->func = ptr;
33863381
head->next = krcp->head;
33873382
krcp->head = head;
33883383
success = true;

0 commit comments

Comments
 (0)