mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
rcu: Make synchronize_rcu_mult() check for duplicates
Currently, doing synchronize_rcu_mult(call_rcu, call_rcu) might (or might not) wait for two RCU grace periods. One approach is of course "don't do that!", but in CONFIG_PREEMPT=n kernels, synchronize_rcu_mult(call_rcu, call_rcu_sched) does exactly that. This results in an ugly #ifdef in sched_cpu_deactivate(). This commit therefore makes __wait_rcu_gp() check for duplicates, which in turn allows duplicates to be passed to synchronize_rcu_mult() without risk of waiting twice on the same type of grace period. Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
This commit is contained in:
parent
a602538e46
commit
68ab0b4263
@ -379,6 +379,7 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
|
|||||||
struct rcu_synchronize *rs_array)
|
struct rcu_synchronize *rs_array)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
/* Initialize and register callbacks for each flavor specified. */
|
/* Initialize and register callbacks for each flavor specified. */
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
@ -390,7 +391,11 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
|
|||||||
}
|
}
|
||||||
init_rcu_head_on_stack(&rs_array[i].head);
|
init_rcu_head_on_stack(&rs_array[i].head);
|
||||||
init_completion(&rs_array[i].completion);
|
init_completion(&rs_array[i].completion);
|
||||||
(crcu_array[i])(&rs_array[i].head, wakeme_after_rcu);
|
for (j = 0; j < i; j++)
|
||||||
|
if (crcu_array[j] == crcu_array[i])
|
||||||
|
break;
|
||||||
|
if (j == i)
|
||||||
|
(crcu_array[i])(&rs_array[i].head, wakeme_after_rcu);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for all callbacks to be invoked. */
|
/* Wait for all callbacks to be invoked. */
|
||||||
@ -399,7 +404,11 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
|
|||||||
(crcu_array[i] == call_rcu ||
|
(crcu_array[i] == call_rcu ||
|
||||||
crcu_array[i] == call_rcu_bh))
|
crcu_array[i] == call_rcu_bh))
|
||||||
continue;
|
continue;
|
||||||
wait_for_completion(&rs_array[i].completion);
|
for (j = 0; j < i; j++)
|
||||||
|
if (crcu_array[j] == crcu_array[i])
|
||||||
|
break;
|
||||||
|
if (j == i)
|
||||||
|
wait_for_completion(&rs_array[i].completion);
|
||||||
destroy_rcu_head_on_stack(&rs_array[i].head);
|
destroy_rcu_head_on_stack(&rs_array[i].head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user