Re: [PATCH v3 tip/core/rcu 1/9] rcu: Add call_rcu_tasks()

Oleg Nesterov
2014-08-01T14:14:27Z

On 07/31, Paul E. McKenney wrote:
>
> +/* Lists of tasks that we are still waiting for during this grace period. */
> +static LIST_HEAD(rcu_tasks_holdouts);

This can be local var in rcu_tasks_kthread()

> + while (!list_empty(&rcu_tasks_holdouts)) {
> + schedule_timeout_interruptible(HZ / 10);
> + flush_signals(current);

Still can't undestand why your paranoia wants flush_signals ;)
This is unneeded and confusing. If you think we can have a bug here,
then we should ot hide it, WARN_ON(signal_pending) would be better.
And if you think signal_pending(current) is possible, why do you
check this only after schedule_interruptible() ?

> + synchronize_sched();
> +
> + /* Invoke the callbacks. */
> + while (list) {
> + next = list->next;
> + local_bh_disable();
> + list->func(list);
> + local_bh_enable();
> + list = next;
> + cond_resched();
> + }

Not sure this makes any sense, but perhaps we can check for the new
callbacks and start the next gp. IOW, the main loop roughly does

for (;;) {
list = rcu_tasks_cbs_head;
rcu_tasks_cbs_head = NULL;

if (!list)
sleep();

synchronize_sched();

wait_for_rcu_tasks_holdout();

synchronize_sched();

process_callbacks(list);
}

we can "join" 2 synchronize_sched's and do

ready_list = NULL;
for (;;) {
list = rcu_tasks_cbs_head;
rcu_tasks_cbs_head = NULL;

if (!list && !ready_list)
sleep();

synchronize_sched();

if (ready_list) {
process_callbacks(ready_list);
ready_list = NULL;
}

if (!list)
continue;

wait_for_rcu_tasks_holdout();
ready_list = list;
}

Oleg.