All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <fweisbec@gmail.com>
To: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Olivier Langlois <olivier@trillion01.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>
Subject: Re: [PATCH 3/8] posix-cpu-timers: fix wrong timer initialization
Date: Wed, 19 Jun 2013 22:56:59 +0200	[thread overview]
Message-ID: <20130619205657.GF21522@somewhere.redhat.com> (raw)
In-Reply-To: <CAHGf_=pzYT9-BLfgX-+0jE2H4CbKChxwp45SwqERC6wu_wSzGw@mail.gmail.com>

On Tue, Jun 18, 2013 at 11:12:17AM -0400, KOSAKI Motohiro wrote:
> On Tue, Jun 18, 2013 at 10:20 AM, Frederic Weisbecker
> <fweisbec@gmail.com> wrote:
> > On Sun, May 26, 2013 at 05:35:44PM -0400, kosaki.motohiro@gmail.com wrote:
> >> From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> >>
> >> Currently glibc's rt/tst-cputimer1 testcase sporadically fails because
> >> a timer created by timer_create() may fire earlier than specified.
> >>
> >> posix_cpu_timer_set() uses "val" as current time for three purpose. 1)
> >> initialize sig->cputimer. 2) calculation "old" val. 3) calculations an
> >> expires.
> >>
> >> (1) and (2) should only use committed time (i.e. without delta_exec)
> >> because run_posix_cpu_timers() don't care of delta_exec and we need
> >> consistency, but (3) need exact current time (aka cpu clock time) because
> >> an expires should be "now + timeout" by definition.
> >>
> >> This patch distinguishes between two kinds of "now".
> >>
> >> Cc: Olivier Langlois <olivier@trillion01.com>
> >> Cc: Thomas Gleixner <tglx@linutronix.de>
> >> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> >> Cc: Ingo Molnar <mingo@kernel.org>
> >> Acked-by: Peter Zijlstra <peterz@infradead.org>
> >> Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> >> ---
> >>  include/linux/kernel_stat.h |    5 -----
> >>  kernel/posix-cpu-timers.c   |   14 ++++++++++++--
> >>  kernel/sched/core.c         |   13 -------------
> >>  3 files changed, 12 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
> >> index ed5f6ed..f5d4fdf 100644
> >> --- a/include/linux/kernel_stat.h
> >> +++ b/include/linux/kernel_stat.h
> >> @@ -117,11 +117,6 @@ static inline unsigned int kstat_cpu_irqs_sum(unsigned int cpu)
> >>       return kstat_cpu(cpu).irqs_sum;
> >>  }
> >>
> >> -/*
> >> - * Lock/unlock the current runqueue - to extract task statistics:
> >> - */
> >> -extern unsigned long long task_delta_exec(struct task_struct *);
> >> -
> >>  extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
> >>  extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
> >>  extern void account_steal_time(cputime_t);
> >> diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
> >> index 25447c5..d068808 100644
> >> --- a/kernel/posix-cpu-timers.c
> >> +++ b/kernel/posix-cpu-timers.c
> >> @@ -652,7 +652,7 @@ static int cpu_timer_sample_group(const clockid_t which_clock,
> >>               cpu->cpu = cputime.utime;
> >>               break;
> >>       case CPUCLOCK_SCHED:
> >> -             cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
> >> +             cpu->sched = cputime.sum_exec_runtime;
> >
> > Are you sure that all callers of cpu_timer_sample_group() are fine with that change?
> 
> Now, cpu_timer_sample_group() is used from following four points.
> 
> posix_cpu_timer_set(): for timer initialization

Right, so to recall what is in your changelog, here we want to:

1) get initial sample and initialize cputime->running to 1, so here
we don't want to commit pending deltas otherwise they may be
accounted twice

2) to compute old value. I would say that here both kind of samples
work (with or without committed pending deltas)

3) set the new timer. We want committed pending deltas here to
compute now + deltas, otherwise the timer might trigger too early

> posix_cpu_timer_get(): for timer_gettime(2)

Here I would say it doesn't matter whether we include pending delta
or not. But just to stay consistent with clock_gettime(), I'd rather
include the pending deltas.

> posix_cpu_timer_schedule(): timer firing

firing or fired. But rescheduling in any case. I would tend to
think we want to include pending deltas as a base to calculate
the next expiry time on top of interval increments, etc...
Pretty much like posix_cpu_timer_set() in fact.

> set_process_cpu_timer(): for itimer

So here the case seem to be very similar to posix_cpu_timer_set()
again.
We pass a relative expiring time delta to setitimer() so we want
the timer to expire at NOW + timeout. So NOW must be the clock
sample that includes the pending deltas that haven't yet been
committed, otherwise the timer may expire too early.

Shouldn't we use cpu_clock_sample_group() here?

> 
> I think all of them are safe because, the point is, timer firing
> procedure (check_thread_timers and check_process_timers) don't care
> uncommitted delta. Then, other timer functions need to use the same
> timer tick. Otherwise the inconsistency leak to userland sooner or
> later.
> 
> The another solution is, check_{thread/process}_timers take plenty rq
> locks and use accurate time. However, of course, it may make lots
> performance hit. So, I don't want
> to take this way.

If only we could commit the pending deltas on the task stats (like calling update_curr())
everytime we check the timer/clock sample. This way we wouldn't worry about all
these pending sum_exec_runtime stuff to be accounted twice and we could just always read it
without further thoughts.

Also, cpu_timer_sample_group() looks to be fundamentally buggy to begin with.
It may add task_delta_exec(p) twice if thread_group_timer() is called with cputimer_running == 0.

> 
> 
> > Looking at set_process_cpu_timer() it seems we want the committed time as well to
> > be added on newval. For the same reasons we use cpu_clock_sample_group() in (3) here.
> 
> Sorry, I haven't caught your point. Could you elaborate more?

See above when I describe my worries on set_process_cpu_timer().

  reply	other threads:[~2013-06-19 20:57 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-26 21:35 [PATCH v5 0/8] posix timers fixlet kosaki.motohiro
2013-05-26 21:35 ` [PATCH 1/8] posix-cpu-timers: don't account cpu timer after stopped thread runtime accounting kosaki.motohiro
2013-05-26 21:35 ` [PATCH 2/8] posix-cpu-timers: fix acounting delta_exec twice kosaki.motohiro
2013-06-03 19:07   ` Frederic Weisbecker
2013-05-26 21:35 ` kosaki.motohiro
2013-05-26 21:35 ` [PATCH 3/8] posix-cpu-timers: fix wrong timer initialization kosaki.motohiro
2013-06-18 14:20   ` Frederic Weisbecker
2013-06-18 15:12     ` KOSAKI Motohiro
2013-06-19 20:56       ` Frederic Weisbecker [this message]
2013-05-26 21:35 ` [PATCH 4/8] posix-cpu-timers: timer functions should use timer time instead of clock time kosaki.motohiro
2013-05-26 21:35 ` [PATCH 5/8] posix-cpu-timers: check_thread_timers() uses task_sched_runtime() kosaki.motohiro
2013-05-26 21:35 ` [PATCH 6/8] sched: task_sched_runtime introduce micro optimization kosaki.motohiro
2013-06-18 14:27   ` Frederic Weisbecker
2013-06-18 15:17     ` KOSAKI Motohiro
2013-06-18 15:28       ` KOSAKI Motohiro
2013-06-18 17:18       ` Frederic Weisbecker
2013-06-20  8:41         ` KOSAKI Motohiro
2013-05-26 21:35 ` [PATCH 7/8] posix-cpu-timers: cleanup cpu_{clock,timer}_sample{,_group} kosaki.motohiro
2013-05-26 21:35 ` [PATCH 8/8] posix-cpu-timers: fix cputimer initialization mistake for {u,s}time kosaki.motohiro
2013-05-31 16:26 ` [PATCH v5 0/8] posix timers fixlet KOSAKI Motohiro

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130619205657.GF21522@somewhere.redhat.com \
    --to=fweisbec@gmail.com \
    --cc=kosaki.motohiro@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=olivier@trillion01.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.