aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/posix-timers.h
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2019-07-31 00:33:54 +0200
committerThomas Gleixner <tglx@linutronix.de>2019-08-01 20:51:25 +0200
commit5d99b32a009e900a561f6a42ea7afe5b21288b8a (patch)
tree212e179aa54bd0b2427aa5d97864a334d9201b85 /include/linux/posix-timers.h
parentposix-timers: Rework cancel retry loops (diff)
downloadlinux-dev-5d99b32a009e900a561f6a42ea7afe5b21288b8a.tar.xz
linux-dev-5d99b32a009e900a561f6a42ea7afe5b21288b8a.zip
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
Diffstat (limited to 'include/linux/posix-timers.h')
-rw-r--r--include/linux/posix-timers.h5
1 files changed, 3 insertions, 2 deletions
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index b20798fc5191..604cec0e41ba 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -85,7 +85,8 @@ static inline int clockid_to_fd(const clockid_t clk)
* @it_process: The task to wakeup on clock_nanosleep (CPU timers)
* @sigq: Pointer to preallocated sigqueue
* @it: Union representing the various posix timer type
- * internals. Also used for rcu freeing the timer.
+ * internals.
+ * @rcu: RCU head for freeing the timer.
*/
struct k_itimer {
struct list_head list;
@@ -114,8 +115,8 @@ struct k_itimer {
struct {
struct alarm alarmtimer;
} alarm;
- struct rcu_head rcu;
} it;
+ struct rcu_head rcu;
};
void run_posix_cpu_timers(struct task_struct *task);