summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch')
-rw-r--r--debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch174
1 files changed, 108 insertions, 66 deletions
diff --git a/debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch b/debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch
index 84581ac96..e7abb5e6a 100644
--- a/debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch
+++ b/debian/patches-rt/posix-timers-thread-posix-cpu-timers-on-rt.patch
@@ -1,7 +1,7 @@
From: John Stultz <johnstul@us.ibm.com>
Date: Fri, 3 Jul 2009 08:29:58 -0500
Subject: posix-timers: Thread posix-cpu-timers on -rt
-Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.2/older/patches-5.2.17-rt9.tar.xz
+Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patches-5.4.3-rt1.tar.xz
posix-cpu-timer code takes non -rt safe locks in hard irq
context. Move it to a thread.
@@ -12,59 +12,39 @@ Signed-off-by: John Stultz <johnstul@us.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
- include/linux/sched.h | 3
- init/init_task.c | 7 +
- kernel/fork.c | 3
- kernel/time/posix-cpu-timers.c | 154 ++++++++++++++++++++++++++++++++++++++++-
- 4 files changed, 164 insertions(+), 3 deletions(-)
+ include/linux/posix-timers.h | 10 ++
+ kernel/time/posix-cpu-timers.c | 175 ++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 174 insertions(+), 11 deletions(-)
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -826,6 +826,9 @@ struct task_struct {
- #ifdef CONFIG_POSIX_TIMERS
- struct task_cputime cputime_expires;
- struct list_head cpu_timers[3];
-+#ifdef CONFIG_PREEMPT_RT_BASE
+--- a/include/linux/posix-timers.h
++++ b/include/linux/posix-timers.h
+@@ -123,6 +123,9 @@ struct posix_cputimers {
+ struct posix_cputimer_base bases[CPUCLOCK_MAX];
+ unsigned int timers_active;
+ unsigned int expiry_active;
++#ifdef CONFIG_PREEMPT_RT
+ struct task_struct *posix_timer_list;
+#endif
- #endif
-
- /* Process credentials: */
---- a/init/init_task.c
-+++ b/init/init_task.c
-@@ -51,6 +51,12 @@ static struct sighand_struct init_sighan
- .signalfd_wqh = __WAIT_QUEUE_HEAD_INITIALIZER(init_sighand.signalfd_wqh),
};
-+#if defined(CONFIG_POSIX_TIMERS) && defined(CONFIG_PREEMPT_RT_BASE)
-+# define INIT_TIMER_LIST .posix_timer_list = NULL,
+ static inline void posix_cputimers_init(struct posix_cputimers *pct)
+@@ -152,9 +155,16 @@ static inline void posix_cputimers_rt_wa
+ INIT_CPU_TIMERBASE(b[2]), \
+ }
+
++#ifdef CONFIG_PREEMPT_RT
++# define INIT_TIMER_LIST .posix_timer_list = NULL,
+#else
+# define INIT_TIMER_LIST
+#endif
+
- /*
- * Set up the first task table, touch at your own risk!. Base=0,
- * limit=0x1fffff (=2MB)
-@@ -120,6 +126,7 @@ struct task_struct init_task
- INIT_CPU_TIMERS(init_task)
- .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock),
- .timer_slack_ns = 50000, /* 50 usec default slack */
-+ INIT_TIMER_LIST
- .thread_pid = &init_struct_pid,
- .thread_group = LIST_HEAD_INIT(init_task.thread_group),
- .thread_node = LIST_HEAD_INIT(init_signals.thread_head),
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -1647,6 +1647,9 @@ static void rt_mutex_init_task(struct ta
- */
- static void posix_cpu_timers_init(struct task_struct *tsk)
- {
-+#ifdef CONFIG_PREEMPT_RT_BASE
-+ tsk->posix_timer_list = NULL;
-+#endif
- tsk->cputime_expires.prof_exp = 0;
- tsk->cputime_expires.virt_exp = 0;
- tsk->cputime_expires.sched_exp = 0;
+ #define INIT_CPU_TIMERS(s) \
+ .posix_cputimers = { \
+ .bases = INIT_CPU_TIMERBASES(s.posix_cputimers.bases), \
++ INIT_TIMER_LIST \
+ },
+ #else
+ struct posix_cputimers { };
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -3,8 +3,10 @@
@@ -86,28 +66,88 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#include "posix-timers.h"
-@@ -1147,15 +1150,13 @@ void cpu_timers_grab_expiry_lock(struct
+@@ -27,6 +30,9 @@ void posix_cputimers_group_init(struct p
+ pct->bases[CPUCLOCK_PROF].nextevt = cpu_limit * NSEC_PER_SEC;
+ pct->timers_active = true;
+ }
++#ifdef CONFIG_PREEMPT_RT
++ pct->posix_timer_list = NULL;
++#endif
+ }
+
+ /*
+@@ -804,7 +810,8 @@ static inline void check_dl_overrun(stru
+ }
+ }
+
+-static bool check_rlimit(u64 time, u64 limit, int signo, bool rt, bool hard)
++static bool check_rlimit(struct task_struct *tsk, u64 time, u64 limit,
++ int signo, bool rt, bool hard)
+ {
+ if (time < limit)
+ return false;
+@@ -812,9 +819,9 @@ static bool check_rlimit(u64 time, u64 l
+ if (print_fatal_signals) {
+ pr_info("%s Watchdog Timeout (%s): %s[%d]\n",
+ rt ? "RT" : "CPU", hard ? "hard" : "soft",
+- current->comm, task_pid_nr(current));
++ tsk->comm, task_pid_nr(tsk));
+ }
+- __group_send_sig_info(signo, SEND_SIG_PRIV, current);
++ __group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
+ return true;
+ }
+
+@@ -850,11 +857,11 @@ static void check_thread_timers(struct t
+
+ /* At the hard limit, send SIGKILL. No further action. */
+ if (hard != RLIM_INFINITY &&
+- check_rlimit(rttime, hard, SIGKILL, true, true))
++ check_rlimit(tsk, rttime, hard, SIGKILL, true, true))
+ return;
+
+ /* At the soft limit, send a SIGXCPU every second */
+- if (check_rlimit(rttime, soft, SIGXCPU, true, false)) {
++ if (check_rlimit(tsk, rttime, soft, SIGXCPU, true, false)) {
+ soft += USEC_PER_SEC;
+ tsk->signal->rlim[RLIMIT_RTTIME].rlim_cur = soft;
+ }
+@@ -949,11 +956,11 @@ static void check_process_timers(struct
+
+ /* At the hard limit, send SIGKILL. No further action. */
+ if (hard != RLIM_INFINITY &&
+- check_rlimit(ptime, hardns, SIGKILL, false, true))
++ check_rlimit(tsk, ptime, hardns, SIGKILL, false, true))
+ return;
+
+ /* At the soft limit, send a SIGXCPU every second */
+- if (check_rlimit(ptime, softns, SIGXCPU, false, false)) {
++ if (check_rlimit(tsk, ptime, softns, SIGXCPU, false, false)) {
+ sig->rlim[RLIMIT_CPU].rlim_cur = soft + 1;
+ softns += NSEC_PER_SEC;
+ }
+@@ -1110,15 +1117,12 @@ static inline bool fastpath_timer_check(
* already updated our counts. We need to check if any timers fire now.
* Interrupts are disabled.
*/
--void run_posix_cpu_timers(struct task_struct *tsk)
+-void run_posix_cpu_timers(void)
+static void __run_posix_cpu_timers(struct task_struct *tsk)
{
- LIST_HEAD(firing);
+- struct task_struct *tsk = current;
struct k_itimer *timer, *next;
unsigned long flags;
- spinlock_t *expiry_lock;
+ LIST_HEAD(firing);
- lockdep_assert_irqs_disabled();
-
/*
* The fast path checks that there are no expired thread or thread
* group timers. If that's so, just return.
-@@ -1215,6 +1216,153 @@ void run_posix_cpu_timers(struct task_st
- spin_unlock(expiry_lock);
+@@ -1171,6 +1175,155 @@ void run_posix_cpu_timers(void)
+ }
}
-+#ifdef CONFIG_PREEMPT_RT_BASE
++#ifdef CONFIG_PREEMPT_RT
+#include <linux/kthread.h>
+#include <linux/cpu.h>
+DEFINE_PER_CPU(struct task_struct *, posix_timer_task);
@@ -134,13 +174,13 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ /* Process task list */
+ while (1) {
+ /* save next */
-+ next = tsk->posix_timer_list;
++ next = tsk->posix_cputimers.posix_timer_list;
+
+ /* run the task timers, clear its ptr and
+ * unreference it
+ */
+ __run_posix_cpu_timers(tsk);
-+ tsk->posix_timer_list = NULL;
++ tsk->posix_cputimers.posix_timer_list = NULL;
+ put_task_struct(tsk);
+
+ /* check if this is the last on the list */
@@ -156,18 +196,19 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ if (unlikely(tsk->exit_state))
+ return 0;
+
-+ if (!task_cputime_zero(&tsk->cputime_expires))
-+ return 1;
++ if (!expiry_cache_is_inactive(&tsk->posix_cputimers))
++ return 1;
+
-+ if (!task_cputime_zero(&tsk->signal->cputime_expires))
-+ return 1;
++ if (!expiry_cache_is_inactive(&tsk->signal->posix_cputimers))
++ return 1;
+
+ return 0;
+}
+
-+void run_posix_cpu_timers(struct task_struct *tsk)
++void run_posix_cpu_timers(void)
+{
+ unsigned int cpu = smp_processor_id();
++ struct task_struct *tsk = current;
+ struct task_struct *tasklist;
+
+ BUG_ON(!irqs_disabled());
@@ -179,16 +220,16 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ tasklist = per_cpu(posix_timer_tasklist, cpu);
+
+ /* check to see if we're already queued */
-+ if (!tsk->posix_timer_list && __fastpath_timer_check(tsk)) {
++ if (!tsk->posix_cputimers.posix_timer_list && __fastpath_timer_check(tsk)) {
+ get_task_struct(tsk);
+ if (tasklist) {
-+ tsk->posix_timer_list = tasklist;
++ tsk->posix_cputimers.posix_timer_list = tasklist;
+ } else {
+ /*
+ * The list is terminated by a self-pointing
+ * task_struct
+ */
-+ tsk->posix_timer_list = tsk;
++ tsk->posix_cputimers.posix_timer_list = tsk;
+ }
+ per_cpu(posix_timer_tasklist, cpu) = tsk;
+
@@ -246,13 +287,14 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+ return 0;
+}
+early_initcall(posix_cpu_thread_init);
-+#else /* CONFIG_PREEMPT_RT_BASE */
-+void run_posix_cpu_timers(struct task_struct *tsk)
++
++#else /* CONFIG_PREEMPT_RT */
++void run_posix_cpu_timers(void)
+{
+ lockdep_assert_irqs_disabled();
-+ __run_posix_cpu_timers(tsk);
++ __run_posix_cpu_timers(current);
+}
-+#endif /* CONFIG_PREEMPT_RT_BASE */
++#endif /* CONFIG_PREEMPT_RT */
+
/*
* Set one of the process-wide special case CPU timers or RLIMIT_CPU.