posix-timers: Move rcu_head out of it union
Timer deletion on PREEMPT_RT is prone to priority inversion and live locks. The hrtimer code has a synchronization mechanism for this. Posix CPU timers will grow one. But that mechanism cannot be invoked while holding the k_itimer lock because that can deadlock against the running timer callback. So the lock must be dropped which allows the timer to be freed. The timer free can be prevented by taking RCU readlock before dropping the lock, but because the rcu_head is part of the 'it' union a concurrent free will overwrite the hrtimer on which the task is trying to synchronize. Move the rcu_head out of the union to prevent this. [ tglx: Fixed up kernel-doc. Rewrote changelog ] Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/20190730223828.965541887@linutronix.de
This commit is contained in:

gecommit door
Thomas Gleixner

bovenliggende
6945e5c2ab
commit
5d99b32a00
@@ -442,7 +442,7 @@ static struct k_itimer * alloc_posix_timer(void)
|
||||
|
||||
static void k_itimer_rcu_free(struct rcu_head *head)
|
||||
{
|
||||
struct k_itimer *tmr = container_of(head, struct k_itimer, it.rcu);
|
||||
struct k_itimer *tmr = container_of(head, struct k_itimer, rcu);
|
||||
|
||||
kmem_cache_free(posix_timers_cache, tmr);
|
||||
}
|
||||
@@ -459,7 +459,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
|
||||
}
|
||||
put_pid(tmr->it_pid);
|
||||
sigqueue_free(tmr->sigq);
|
||||
call_rcu(&tmr->it.rcu, k_itimer_rcu_free);
|
||||
call_rcu(&tmr->rcu, k_itimer_rcu_free);
|
||||
}
|
||||
|
||||
static int common_timer_create(struct k_itimer *new_timer)
|
||||
|
Verwijs in nieuw issue
Block a user