]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/time/posix-cpu-timers.c
Merge branches 'pm-core', 'pm-qos', 'pm-domains' and 'pm-opp'
[linux.git] / kernel / time / posix-cpu-timers.c
index 8349e02b1c0c081086dff6cb97973c5aa9514077..b4377a5e42694873867fc1b91ef93a48479b9180 100644 (file)
  */
 void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new)
 {
-       cputime_t cputime = secs_to_cputime(rlim_new);
+       u64 nsecs = rlim_new * NSEC_PER_SEC;
 
        spin_lock_irq(&task->sighand->siglock);
-       set_process_cpu_timer(task, CPUCLOCK_PROF, &cputime, NULL);
+       set_process_cpu_timer(task, CPUCLOCK_PROF, &nsecs, NULL);
        spin_unlock_irq(&task->sighand->siglock);
 }
 
@@ -50,39 +50,14 @@ static int check_clock(const clockid_t which_clock)
        return error;
 }
 
-static inline unsigned long long
-timespec_to_sample(const clockid_t which_clock, const struct timespec *tp)
-{
-       unsigned long long ret;
-
-       ret = 0;                /* high half always zero when .cpu used */
-       if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
-               ret = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;
-       } else {
-               ret = cputime_to_expires(timespec_to_cputime(tp));
-       }
-       return ret;
-}
-
-static void sample_to_timespec(const clockid_t which_clock,
-                              unsigned long long expires,
-                              struct timespec *tp)
-{
-       if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED)
-               *tp = ns_to_timespec(expires);
-       else
-               cputime_to_timespec((__force cputime_t)expires, tp);
-}
-
 /*
  * Update expiry time from increment, and increase overrun count,
  * given the current clock sample.
  */
-static void bump_cpu_timer(struct k_itimer *timer,
-                          unsigned long long now)
+static void bump_cpu_timer(struct k_itimer *timer, u64 now)
 {
        int i;
-       unsigned long long delta, incr;
+       u64 delta, incr;
 
        if (timer->it.cpu.incr == 0)
                return;
@@ -115,28 +90,28 @@ static void bump_cpu_timer(struct k_itimer *timer,
  * Checks @cputime to see if all fields are zero.  Returns true if all fields
  * are zero, false if any field is nonzero.
  */
-static inline int task_cputime_zero(const struct task_cputime_t *cputime)
+static inline int task_cputime_zero(const struct task_cputime *cputime)
 {
        if (!cputime->utime && !cputime->stime && !cputime->sum_exec_runtime)
                return 1;
        return 0;
 }
 
-static inline unsigned long long prof_ticks(struct task_struct *p)
+static inline u64 prof_ticks(struct task_struct *p)
 {
-       cputime_t utime, stime;
+       u64 utime, stime;
 
-       task_cputime_t(p, &utime, &stime);
+       task_cputime(p, &utime, &stime);
 
-       return cputime_to_expires(utime + stime);
+       return utime + stime;
 }
-static inline unsigned long long virt_ticks(struct task_struct *p)
+static inline u64 virt_ticks(struct task_struct *p)
 {
-       cputime_t utime, stime;
+       u64 utime, stime;
 
-       task_cputime_t(p, &utime, &stime);
+       task_cputime(p, &utime, &stime);
 
-       return cputime_to_expires(utime);
+       return utime;
 }
 
 static int
@@ -176,8 +151,8 @@ posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)
 /*
  * Sample a per-thread clock for the given task.
  */
-static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
-                           unsigned long long *sample)
+static int cpu_clock_sample(const clockid_t which_clock,
+                           struct task_struct *p, u64 *sample)
 {
        switch (CPUCLOCK_WHICH(which_clock)) {
        default:
@@ -210,7 +185,7 @@ static inline void __update_gt_cputime(atomic64_t *cputime, u64 sum_cputime)
        }
 }
 
-static void update_gt_cputime(struct task_cputime_atomic *cputime_atomic, struct task_cputime_t *sum)
+static void update_gt_cputime(struct task_cputime_atomic *cputime_atomic, struct task_cputime *sum)
 {
        __update_gt_cputime(&cputime_atomic->utime, sum->utime);
        __update_gt_cputime(&cputime_atomic->stime, sum->stime);
@@ -218,7 +193,7 @@ static void update_gt_cputime(struct task_cputime_atomic *cputime_atomic, struct
 }
 
 /* Sample task_cputime_atomic values in "atomic_timers", store results in "times". */
-static inline void sample_cputime_atomic(struct task_cputime_t *times,
+static inline void sample_cputime_atomic(struct task_cputime *times,
                                         struct task_cputime_atomic *atomic_times)
 {
        times->utime = atomic64_read(&atomic_times->utime);
@@ -226,10 +201,10 @@ static inline void sample_cputime_atomic(struct task_cputime_t *times,
        times->sum_exec_runtime = atomic64_read(&atomic_times->sum_exec_runtime);
 }
 
-void thread_group_cputimer(struct task_struct *tsk, struct task_cputime_t *times)
+void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
 {
        struct thread_group_cputimer *cputimer = &tsk->signal->cputimer;
-       struct task_cputime_t sum;
+       struct task_cputime sum;
 
        /* Check if cputimer isn't running. This is accessed without locking. */
        if (!READ_ONCE(cputimer->running)) {
@@ -238,7 +213,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime_t *times
                 * values through the TIMER_ABSTIME flag, therefore we have
                 * to synchronize the timer to the clock every time we start it.
                 */
-               thread_group_cputime_t(tsk, &sum);
+               thread_group_cputime(tsk, &sum);
                update_gt_cputime(&cputimer->cputime_atomic, &sum);
 
                /*
@@ -260,23 +235,23 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime_t *times
  */
 static int cpu_clock_sample_group(const clockid_t which_clock,
                                  struct task_struct *p,
-                                 unsigned long long *sample)
+                                 u64 *sample)
 {
-       struct task_cputime_t cputime;
+       struct task_cputime cputime;
 
        switch (CPUCLOCK_WHICH(which_clock)) {
        default:
                return -EINVAL;
        case CPUCLOCK_PROF:
-               thread_group_cputime_t(p, &cputime);
-               *sample = cputime_to_expires(cputime.utime + cputime.stime);
+               thread_group_cputime(p, &cputime);
+               *sample = cputime.utime + cputime.stime;
                break;
        case CPUCLOCK_VIRT:
-               thread_group_cputime_t(p, &cputime);
-               *sample = cputime_to_expires(cputime.utime);
+               thread_group_cputime(p, &cputime);
+               *sample = cputime.utime;
                break;
        case CPUCLOCK_SCHED:
-               thread_group_cputime_t(p, &cputime);
+               thread_group_cputime(p, &cputime);
                *sample = cputime.sum_exec_runtime;
                break;
        }
@@ -288,7 +263,7 @@ static int posix_cpu_clock_get_task(struct task_struct *tsk,
                                    struct timespec *tp)
 {
        int err = -EINVAL;
-       unsigned long long rtn;
+       u64 rtn;
 
        if (CPUCLOCK_PERTHREAD(which_clock)) {
                if (same_thread_group(tsk, current))
@@ -299,7 +274,7 @@ static int posix_cpu_clock_get_task(struct task_struct *tsk,
        }
 
        if (!err)
-               sample_to_timespec(which_clock, rtn, tp);
+               *tp = ns_to_timespec(rtn);
 
        return err;
 }
@@ -453,7 +428,7 @@ void posix_cpu_timers_exit_group(struct task_struct *tsk)
        cleanup_timers(tsk->signal->cpu_timers);
 }
 
-static inline int expires_gt(cputime_t expires, cputime_t new_exp)
+static inline int expires_gt(u64 expires, u64 new_exp)
 {
        return expires == 0 || expires > new_exp;
 }
@@ -466,7 +441,7 @@ static void arm_timer(struct k_itimer *timer)
 {
        struct task_struct *p = timer->it.cpu.task;
        struct list_head *head, *listpos;
-       struct task_cputime_t *cputime_expires;
+       struct task_cputime *cputime_expires;
        struct cpu_timer_list *const nt = &timer->it.cpu;
        struct cpu_timer_list *next;
 
@@ -488,7 +463,7 @@ static void arm_timer(struct k_itimer *timer)
        list_add(&nt->entry, listpos);
 
        if (listpos == head) {
-               unsigned long long exp = nt->expires;
+               u64 exp = nt->expires;
 
                /*
                 * We are the new earliest-expiring POSIX 1.b timer, hence
@@ -499,16 +474,15 @@ static void arm_timer(struct k_itimer *timer)
 
                switch (CPUCLOCK_WHICH(timer->it_clock)) {
                case CPUCLOCK_PROF:
-                       if (expires_gt(cputime_expires->prof_exp, expires_to_cputime(exp)))
-                               cputime_expires->prof_exp = expires_to_cputime(exp);
+                       if (expires_gt(cputime_expires->prof_exp, exp))
+                               cputime_expires->prof_exp = exp;
                        break;
                case CPUCLOCK_VIRT:
-                       if (expires_gt(cputime_expires->virt_exp, expires_to_cputime(exp)))
-                               cputime_expires->virt_exp = expires_to_cputime(exp);
+                       if (expires_gt(cputime_expires->virt_exp, exp))
+                               cputime_expires->virt_exp = exp;
                        break;
                case CPUCLOCK_SCHED:
-                       if (cputime_expires->sched_exp == 0 ||
-                           cputime_expires->sched_exp > exp)
+                       if (expires_gt(cputime_expires->sched_exp, exp))
                                cputime_expires->sched_exp = exp;
                        break;
                }
@@ -559,20 +533,19 @@ static void cpu_timer_fire(struct k_itimer *timer)
  * traversal.
  */
 static int cpu_timer_sample_group(const clockid_t which_clock,
-                                 struct task_struct *p,
-                                 unsigned long long *sample)
+                                 struct task_struct *p, u64 *sample)
 {
-       struct task_cputime_t cputime;
+       struct task_cputime cputime;
 
        thread_group_cputimer(p, &cputime);
        switch (CPUCLOCK_WHICH(which_clock)) {
        default:
                return -EINVAL;
        case CPUCLOCK_PROF:
-               *sample = cputime_to_expires(cputime.utime + cputime.stime);
+               *sample = cputime.utime + cputime.stime;
                break;
        case CPUCLOCK_VIRT:
-               *sample = cputime_to_expires(cputime.utime);
+               *sample = cputime.utime;
                break;
        case CPUCLOCK_SCHED:
                *sample = cputime.sum_exec_runtime;
@@ -593,12 +566,12 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
        unsigned long flags;
        struct sighand_struct *sighand;
        struct task_struct *p = timer->it.cpu.task;
-       unsigned long long old_expires, new_expires, old_incr, val;
+       u64 old_expires, new_expires, old_incr, val;
        int ret;
 
        WARN_ON_ONCE(p == NULL);
 
-       new_expires = timespec_to_sample(timer->it_clock, &new->it_value);
+       new_expires = timespec_to_ns(&new->it_value);
 
        /*
         * Protect against sighand release/switch in exit/exec and p->cpu_timers
@@ -659,9 +632,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
                        bump_cpu_timer(timer, val);
                        if (val < timer->it.cpu.expires) {
                                old_expires = timer->it.cpu.expires - val;
-                               sample_to_timespec(timer->it_clock,
-                                                  old_expires,
-                                                  &old->it_value);
+                               old->it_value = ns_to_timespec(old_expires);
                        } else {
                                old->it_value.tv_nsec = 1;
                                old->it_value.tv_sec = 0;
@@ -699,8 +670,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
         * Install the new reload setting, and
         * set up the signal and overrun bookkeeping.
         */
-       timer->it.cpu.incr = timespec_to_sample(timer->it_clock,
-                                               &new->it_interval);
+       timer->it.cpu.incr = timespec_to_ns(&new->it_interval);
 
        /*
         * This acts as a modification timestamp for the timer,
@@ -723,17 +693,15 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int timer_flags,
 
        ret = 0;
  out:
-       if (old) {
-               sample_to_timespec(timer->it_clock,
-                                  old_incr, &old->it_interval);
-       }
+       if (old)
+               old->it_interval = ns_to_timespec(old_incr);
 
        return ret;
 }
 
 static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
 {
-       unsigned long long now;
+       u64 now;
        struct task_struct *p = timer->it.cpu.task;
 
        WARN_ON_ONCE(p == NULL);
@@ -741,8 +709,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
        /*
         * Easy part: convert the reload time.
         */
-       sample_to_timespec(timer->it_clock,
-                          timer->it.cpu.incr, &itp->it_interval);
+       itp->it_interval = ns_to_timespec(timer->it.cpu.incr);
 
        if (timer->it.cpu.expires == 0) {       /* Timer not armed at all.  */
                itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;
@@ -761,7 +728,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
                /*
                 * Protect against sighand release/switch in exit/exec and
                 * also make timer sampling safe if it ends up calling
-                * thread_group_cputime_t().
+                * thread_group_cputime().
                 */
                sighand = lock_task_sighand(p, &flags);
                if (unlikely(sighand == NULL)) {
@@ -771,8 +738,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
                         * Call the timer disarmed, nothing else to do.
                         */
                        timer->it.cpu.expires = 0;
-                       sample_to_timespec(timer->it_clock, timer->it.cpu.expires,
-                                          &itp->it_value);
+                       itp->it_value = ns_to_timespec(timer->it.cpu.expires);
                        return;
                } else {
                        cpu_timer_sample_group(timer->it_clock, p, &now);
@@ -781,9 +747,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
        }
 
        if (now < timer->it.cpu.expires) {
-               sample_to_timespec(timer->it_clock,
-                                  timer->it.cpu.expires - now,
-                                  &itp->it_value);
+               itp->it_value = ns_to_timespec(timer->it.cpu.expires - now);
        } else {
                /*
                 * The timer should have expired already, but the firing
@@ -826,8 +790,8 @@ static void check_thread_timers(struct task_struct *tsk,
 {
        struct list_head *timers = tsk->cpu_timers;
        struct signal_struct *const sig = tsk->signal;
-       struct task_cputime_t *tsk_expires = &tsk->cputime_expires;
-       unsigned long long expires;
+       struct task_cputime *tsk_expires = &tsk->cputime_expires;
+       u64 expires;
        unsigned long soft;
 
        /*
@@ -838,10 +802,10 @@ static void check_thread_timers(struct task_struct *tsk,
                return;
 
        expires = check_timers_list(timers, firing, prof_ticks(tsk));
-       tsk_expires->prof_exp = expires_to_cputime(expires);
+       tsk_expires->prof_exp = expires;
 
        expires = check_timers_list(++timers, firing, virt_ticks(tsk));
-       tsk_expires->virt_exp = expires_to_cputime(expires);
+       tsk_expires->virt_exp = expires;
 
        tsk_expires->sched_exp = check_timers_list(++timers, firing,
                                                   tsk->se.sum_exec_runtime);
@@ -891,23 +855,16 @@ static inline void stop_process_timers(struct signal_struct *sig)
 }
 
 static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
-                            unsigned long long *expires,
-                            unsigned long long cur_time, int signo)
+                            u64 *expires, u64 cur_time, int signo)
 {
        if (!it->expires)
                return;
 
        if (cur_time >= it->expires) {
-               if (it->incr) {
+               if (it->incr)
                        it->expires += it->incr;
-                       it->error += it->incr_error;
-                       if (it->error >= TICK_NSEC) {
-                               it->expires -= cputime_one_jiffy;
-                               it->error -= TICK_NSEC;
-                       }
-               } else {
+               else
                        it->expires = 0;
-               }
 
                trace_itimer_expire(signo == SIGPROF ?
                                    ITIMER_PROF : ITIMER_VIRTUAL,
@@ -915,9 +872,8 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
                __group_send_sig_info(signo, SEND_SIG_PRIV, tsk);
        }
 
-       if (it->expires && (!*expires || it->expires < *expires)) {
+       if (it->expires && (!*expires || it->expires < *expires))
                *expires = it->expires;
-       }
 }
 
 /*
@@ -929,10 +885,10 @@ static void check_process_timers(struct task_struct *tsk,
                                 struct list_head *firing)
 {
        struct signal_struct *const sig = tsk->signal;
-       unsigned long long utime, ptime, virt_expires, prof_expires;
-       unsigned long long sum_sched_runtime, sched_expires;
+       u64 utime, ptime, virt_expires, prof_expires;
+       u64 sum_sched_runtime, sched_expires;
        struct list_head *timers = sig->cpu_timers;
-       struct task_cputime_t cputime;
+       struct task_cputime cputime;
        unsigned long soft;
 
        /*
@@ -952,8 +908,8 @@ static void check_process_timers(struct task_struct *tsk,
         * Collect the current process totals.
         */
        thread_group_cputimer(tsk, &cputime);
-       utime = cputime_to_expires(cputime.utime);
-       ptime = utime + cputime_to_expires(cputime.stime);
+       utime = cputime.utime;
+       ptime = utime + cputime.stime;
        sum_sched_runtime = cputime.sum_exec_runtime;
 
        prof_expires = check_timers_list(timers, firing, ptime);
@@ -969,10 +925,10 @@ static void check_process_timers(struct task_struct *tsk,
                         SIGVTALRM);
        soft = READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
        if (soft != RLIM_INFINITY) {
-               unsigned long psecs = cputime_to_secs(ptime);
+               unsigned long psecs = div_u64(ptime, NSEC_PER_SEC);
                unsigned long hard =
                        READ_ONCE(sig->rlim[RLIMIT_CPU].rlim_max);
-               cputime_t x;
+               u64 x;
                if (psecs >= hard) {
                        /*
                         * At the hard limit, we just die.
@@ -991,14 +947,13 @@ static void check_process_timers(struct task_struct *tsk,
                                sig->rlim[RLIMIT_CPU].rlim_cur = soft;
                        }
                }
-               x = secs_to_cputime(soft);
-               if (!prof_expires || x < prof_expires) {
+               x = soft * NSEC_PER_SEC;
+               if (!prof_expires || x < prof_expires)
                        prof_expires = x;
-               }
        }
 
-       sig->cputime_expires.prof_exp = expires_to_cputime(prof_expires);
-       sig->cputime_expires.virt_exp = expires_to_cputime(virt_expires);
+       sig->cputime_expires.prof_exp = prof_expires;
+       sig->cputime_expires.virt_exp = virt_expires;
        sig->cputime_expires.sched_exp = sched_expires;
        if (task_cputime_zero(&sig->cputime_expires))
                stop_process_timers(sig);
@@ -1015,7 +970,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
        struct sighand_struct *sighand;
        unsigned long flags;
        struct task_struct *p = timer->it.cpu.task;
-       unsigned long long now;
+       u64 now;
 
        WARN_ON_ONCE(p == NULL);
 
@@ -1035,7 +990,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
        } else {
                /*
                 * Protect arm_timer() and timer sampling in case of call to
-                * thread_group_cputime_t().
+                * thread_group_cputime().
                 */
                sighand = lock_task_sighand(p, &flags);
                if (unlikely(sighand == NULL)) {
@@ -1078,8 +1033,8 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
  * Returns true if any field of the former is greater than the corresponding
  * field of the latter if the latter field is set.  Otherwise returns false.
  */
-static inline int task_cputime_expired(const struct task_cputime_t *sample,
-                                       const struct task_cputime_t *expires)
+static inline int task_cputime_expired(const struct task_cputime *sample,
+                                       const struct task_cputime *expires)
 {
        if (expires->utime && sample->utime >= expires->utime)
                return 1;
@@ -1106,9 +1061,9 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
        struct signal_struct *sig;
 
        if (!task_cputime_zero(&tsk->cputime_expires)) {
-               struct task_cputime_t task_sample;
+               struct task_cputime task_sample;
 
-               task_cputime_t(tsk, &task_sample.utime, &task_sample.stime);
+               task_cputime(tsk, &task_sample.utime, &task_sample.stime);
                task_sample.sum_exec_runtime = tsk->se.sum_exec_runtime;
                if (task_cputime_expired(&task_sample, &tsk->cputime_expires))
                        return 1;
@@ -1131,7 +1086,7 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
         */
        if (READ_ONCE(sig->cputimer.running) &&
            !READ_ONCE(sig->cputimer.checking_timer)) {
-               struct task_cputime_t group_sample;
+               struct task_cputime group_sample;
 
                sample_cputime_atomic(&group_sample, &sig->cputimer.cputime_atomic);
 
@@ -1212,9 +1167,9 @@ void run_posix_cpu_timers(struct task_struct *tsk)
  * The tsk->sighand->siglock must be held by the caller.
  */
 void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
-                          cputime_t *newval, cputime_t *oldval)
+                          u64 *newval, u64 *oldval)
 {
-       unsigned long long now;
+       u64 now;
 
        WARN_ON_ONCE(clock_idx == CPUCLOCK_SCHED);
        cpu_timer_sample_group(clock_idx, tsk, &now);
@@ -1228,7 +1183,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
                if (*oldval) {
                        if (*oldval <= now) {
                                /* Just about to fire. */
-                               *oldval = cputime_one_jiffy;
+                               *oldval = TICK_NSEC;
                        } else {
                                *oldval -= now;
                        }
@@ -1308,7 +1263,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,
                /*
                 * We were interrupted by a signal.
                 */
-               sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp);
+               *rqtp = ns_to_timespec(timer.it.cpu.expires);
                error = posix_cpu_timer_set(&timer, 0, &zero_it, it);
                if (!error) {
                        /*