Merge branch 'sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / kernel / time / posix-cpu-timers.c
index 1f27887aa19487e82950498485bc83a295098104..2541bd89f20eb95f96d435d21f4eb7c4d1a0cda6 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/tick.h>
 #include <linux/workqueue.h>
 #include <linux/compat.h>
+#include <linux/sched/deadline.h>
 
 #include "posix-timers.h"
 
@@ -791,6 +792,14 @@ check_timers_list(struct list_head *timers,
        return 0;
 }
 
+static inline void check_dl_overrun(struct task_struct *tsk)
+{
+       if (tsk->dl.dl_overrun) {
+               tsk->dl.dl_overrun = 0;
+               __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
+       }
+}
+
 /*
  * Check for any per-thread CPU timers that have fired and move them off
  * the tsk->cpu_timers[N] list onto the firing list.  Here we update the
@@ -804,6 +813,9 @@ static void check_thread_timers(struct task_struct *tsk,
        u64 expires;
        unsigned long soft;
 
+       if (dl_task(tsk))
+               check_dl_overrun(tsk);
+
        /*
         * If cputime_expires is zero, then there are no active
         * per thread CPU timers.
@@ -906,6 +918,9 @@ static void check_process_timers(struct task_struct *tsk,
        struct task_cputime cputime;
        unsigned long soft;
 
+       if (dl_task(tsk))
+               check_dl_overrun(tsk);
+
        /*
         * If cputimer is not running, then there are no active
         * process wide timers (POSIX 1.b, itimers, RLIMIT_CPU).
@@ -1111,6 +1126,9 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
                        return 1;
        }
 
+       if (dl_task(tsk) && tsk->dl.dl_overrun)
+               return 1;
+
        return 0;
 }
 
@@ -1189,9 +1207,8 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
        u64 now;
 
        WARN_ON_ONCE(clock_idx == CPUCLOCK_SCHED);
-       cpu_timer_sample_group(clock_idx, tsk, &now);
 
-       if (oldval) {
+       if (oldval && cpu_timer_sample_group(clock_idx, tsk, &now) != -EINVAL) {
                /*
                 * We are setting itimer. The *oldval is absolute and we update
                 * it to be relative, *newval argument is relative and we update
@@ -1363,8 +1380,8 @@ static long posix_cpu_nsleep_restart(struct restart_block *restart_block)
        return do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t);
 }
 
-#define PROCESS_CLOCK  MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED)
-#define THREAD_CLOCK   MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED)
+#define PROCESS_CLOCK  make_process_cpuclock(0, CPUCLOCK_SCHED)
+#define THREAD_CLOCK   make_thread_cpuclock(0, CPUCLOCK_SCHED)
 
 static int process_cpu_clock_getres(const clockid_t which_clock,
                                    struct timespec64 *tp)