lkml.org 
[lkml]   [2009]   [May]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH resend3 2/2] itimers: fix periodic tics precision
On Mon, 18 May 2009, Stanislaw Gruszka wrote:
> int do_getitimer(int which, struct itimerval *value)
> @@ -133,18 +134,20 @@ enum hrtimer_restart it_real_fn(struct hrtimer *timer)
> }
>
> static void set_cpu_itimer(struct task_struct *tsk, unsigned int clock_id,
> - struct itimerval *value, struct itimerval *ovalue)
> + const struct itimerval *const value,
> + struct itimerval *const ovalue)
> {
> - cputime_t cval, cinterval, nval, ninterval;
> + cputime_t cval, nval;
> + ktime_t kt_cinterval, kt_ninterval;

Just nitpicking. That kt_ prefix is not really helpful, but that's
my personal taste :)

> diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
> index b6accca..905734b 100644
> --- a/kernel/posix-cpu-timers.c
> +++ b/kernel/posix-cpu-timers.c
> @@ -1080,9 +1080,27 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
> return;
>
> if (cputime_ge(cur_time, it->expires)) {
> - it->expires = it->incr;
> - if (!cputime_eq(it->expires, cputime_zero)) {
> - it->expires = cputime_add(it->expires, cur_time);
> + if (it->incr.tv64 != 0) {
> + ktime_t incr, real_incr, diff;
> + cputime_t cpu_incr;
> + struct timespec ts_incr, ts_real_incr;
> +
> + incr = ktime_sub_ns(it->incr, it->err_ns);
> + if (unlikely(incr.tv64 <= 0))
> + incr = ktime_set(0, 1);
> +
> + ts_incr = ktime_to_timespec(incr);
> + cpu_incr = timespec_to_cputime(&ts_incr);
> +
> + cputime_to_timespec(cpu_incr, &ts_real_incr);
> + real_incr = timespec_to_ktime(ts_real_incr);

Yuck, we convert back and forth here. That's lots of really
expensive math operations.

ktime -> timespec -> cputime -> timespec -> ktime

Isn't there a more intelligent way to get the delta ?

We can precompute the real (cputime) increment of the given
increment value, which should be always >= the precise increment
value. We also can precompute the ktime_t value of one cputime
increment.

So now we can do:

it->expires = cputime_add(it->expires, it->cpu_incr);
it->error = ktime_add(it->error, it->incr_error);
if (it->error.tv64 >= onecputimetick.tv64) {
it->expires--;
it->error = ktime_sub(it->error, onecputimetick);
}

And the whole function boils down to simple add/sub/compare math.

Thanks,

tglx


\
 
 \ /
  Last update: 2009-05-19 16:59    [W:1.134 / U:0.748 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site