Skip to content

Commit 462df2f

Browse files
committed
rcu: Support direct wake-up of synchronize_rcu() users
This patch introduces a small enhancement which allows to do a direct wake-up of synchronize_rcu() callers. It occurs after a completion of grace period, thus by the gp-kthread. Number of clients is limited by the hard-coded maximum allowed threshold. The remaining part, if still exists is deferred to a main worker. Link: https://lore.kernel.org/lkml/Zd0ZtNu+Rt0qXkfS@lothringen/ Reviewed-by: Paul E. McKenney <[email protected]> Signed-off-by: Uladzislau Rezki (Sony) <[email protected]>
1 parent 2053937 commit 462df2f

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

kernel/rcu/tree.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,19 +1645,41 @@ static void rcu_sr_normal_gp_cleanup_work(struct work_struct *work)
16451645
*/
16461646
static void rcu_sr_normal_gp_cleanup(void)
16471647
{
1648-
struct llist_node *wait_tail;
1648+
struct llist_node *wait_tail, *next, *rcu;
1649+
int done = 0;
16491650

16501651
wait_tail = rcu_state.srs_wait_tail;
16511652
if (wait_tail == NULL)
16521653
return;
16531654

16541655
rcu_state.srs_wait_tail = NULL;
16551656
ASSERT_EXCLUSIVE_WRITER(rcu_state.srs_wait_tail);
1657+
WARN_ON_ONCE(!rcu_sr_is_wait_head(wait_tail));
1658+
1659+
/*
1660+
* Process (a) and (d) cases. See an illustration.
1661+
*/
1662+
llist_for_each_safe(rcu, next, wait_tail->next) {
1663+
if (rcu_sr_is_wait_head(rcu))
1664+
break;
1665+
1666+
rcu_sr_normal_complete(rcu);
1667+
// It can be last, update a next on this step.
1668+
wait_tail->next = next;
1669+
1670+
if (++done == SR_MAX_USERS_WAKE_FROM_GP)
1671+
break;
1672+
}
16561673

16571674
// concurrent sr_normal_gp_cleanup work might observe this update.
16581675
smp_store_release(&rcu_state.srs_done_tail, wait_tail);
16591676
ASSERT_EXCLUSIVE_WRITER(rcu_state.srs_done_tail);
16601677

1678+
/*
1679+
* We schedule a work in order to perform a final processing
1680+
* of outstanding users(if still left) and releasing wait-heads
1681+
* added by rcu_sr_normal_gp_init() call.
1682+
*/
16611683
schedule_work(&rcu_state.srs_cleanup_work);
16621684
}
16631685

kernel/rcu/tree.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ do { \
315315
__set_current_state(TASK_RUNNING); \
316316
} while (0)
317317

318+
/*
319+
* A max threshold for synchronize_rcu() users which are
320+
* awaken directly by the rcu_gp_kthread(). Left part is
321+
* deferred to the main worker.
322+
*/
323+
#define SR_MAX_USERS_WAKE_FROM_GP 5
318324
#define SR_NORMAL_GP_WAIT_HEAD_MAX 5
319325

320326
struct sr_wait_node {

0 commit comments

Comments
 (0)