Skip to content

Commit 8fc5494

Browse files
urezkipaulmckrcu
authored andcommitted
rcu/kvfree: Move need_offload_krc() out of krcp->lock
The need_offload_krc() function currently holds the krcp->lock in order to safely check krcp->head. This commit removes the need for this lock in that function by updating the krcp->head pointer using WRITE_ONCE() macro so that readers can carry out lockless loads of that pointer. Signed-off-by: Uladzislau Rezki (Sony) <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 8c15a9e commit 8fc5494

File tree

1 file changed

+4
-7
lines changed

1 file changed

+4
-7
lines changed

kernel/rcu/tree.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,7 +3194,7 @@ static void kfree_rcu_monitor(struct work_struct *work)
31943194
// objects queued on the linked list.
31953195
if (!krwp->head_free) {
31963196
krwp->head_free = krcp->head;
3197-
krcp->head = NULL;
3197+
WRITE_ONCE(krcp->head, NULL);
31983198
}
31993199

32003200
WRITE_ONCE(krcp->count, 0);
@@ -3208,15 +3208,15 @@ static void kfree_rcu_monitor(struct work_struct *work)
32083208
}
32093209
}
32103210

3211+
raw_spin_unlock_irqrestore(&krcp->lock, flags);
3212+
32113213
// If there is nothing to detach, it means that our job is
32123214
// successfully done here. In case of having at least one
32133215
// of the channels that is still busy we should rearm the
32143216
// work to repeat an attempt. Because previous batches are
32153217
// still in progress.
32163218
if (need_offload_krc(krcp))
32173219
schedule_delayed_monitor_work(krcp);
3218-
3219-
raw_spin_unlock_irqrestore(&krcp->lock, flags);
32203220
}
32213221

32223222
static enum hrtimer_restart
@@ -3386,7 +3386,7 @@ void kvfree_call_rcu(struct rcu_head *head, void *ptr)
33863386

33873387
head->func = ptr;
33883388
head->next = krcp->head;
3389-
krcp->head = head;
3389+
WRITE_ONCE(krcp->head, head);
33903390
success = true;
33913391
}
33923392

@@ -3463,15 +3463,12 @@ static struct shrinker kfree_rcu_shrinker = {
34633463
void __init kfree_rcu_scheduler_running(void)
34643464
{
34653465
int cpu;
3466-
unsigned long flags;
34673466

34683467
for_each_possible_cpu(cpu) {
34693468
struct kfree_rcu_cpu *krcp = per_cpu_ptr(&krc, cpu);
34703469

3471-
raw_spin_lock_irqsave(&krcp->lock, flags);
34723470
if (need_offload_krc(krcp))
34733471
schedule_delayed_monitor_work(krcp);
3474-
raw_spin_unlock_irqrestore(&krcp->lock, flags);
34753472
}
34763473
}
34773474

0 commit comments

Comments
 (0)