All of lore.kernel.org
 help / color / mirror / Atom feed
From: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: kosaki.motohiro@gmail.com, linux-kernel@vger.kernel.org,
	KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>,
	Olivier Langlois <olivier@trillion01.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	David Miller <davem@davemloft.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	Frederic Weisbecker <fweisbec@gmail.com>,
	Ingo Molnar <mingo@kernel.org>
Subject: Re: [PATCH 2/2] posix-cpu-timers: fix wrong timer initialization
Date: Mon, 29 Apr 2013 13:53:56 -0400	[thread overview]
Message-ID: <517EB3B4.6040702@gmail.com> (raw)
In-Reply-To: <20130429103600.GB31700@dyad.programming.kicks-ass.net>

(4/29/13 6:36 AM), Peter Zijlstra wrote:
> On Mon, Apr 29, 2013 at 02:26:02AM -0400, kosaki.motohiro@gmail.com wrote:
>> From: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
>>
>> Currently glibc's rt/tst-cputimer1 testcase is spradically fail because
>> a timer created by timer_create() may faire earlier than an argument.
>>
>> There are two faults. 1) cpu_timer_sample_group() adds task_delta_exec(current).
>> But it is definity silly idea especially when multi thread. cputimer should
>> be initialized by committed exec runtime. i.e. it should not be added
>> scheduler delta. 2) expire time should be current time + timeout. In the other
>> words, expire calculation should take care scheduler delta.
> 
> I'm sorry, that completely fails to parse.
> 
>> -/*
>> - * Lock/unlock the current runqueue - to extract task statistics:
>> - */
>> -extern unsigned long long task_delta_exec(struct task_struct *);
> 
> Yay.. this thing dying is good -- it did seem strange to compute the current
> delta but not also read sum_exec_runtime under the same lock.
> 
>> diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
>> index e56be4c..dc61bc3 100644
>> --- a/kernel/posix-cpu-timers.c
>> +++ b/kernel/posix-cpu-timers.c
>> @@ -203,12 +203,10 @@ posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)
>>  	return error;
>>  }
>>  
>> -
>> -/*
>> - * Sample a per-thread clock for the given task.
>> - */
>> -static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
>> -			    union cpu_time_count *cpu)
>> +static int do_cpu_clock_sample(const clockid_t which_clock,
>> +			       struct task_struct *p,
>> +			       bool add_delta,
>> +			       union cpu_time_count *cpu)
> 
> Would not thread_cputime() (to mirror thread_group_cputime()) be a better name?

agreed.


> Also, I would think both these functions would be a good place to insert a
> comment explaining the difference between timer and clock.

agreed.


> 
>> +static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
>> +			    union cpu_time_count *cpu)
>> +{
>> +	return do_cpu_clock_sample(which_clock, p, true, cpu);
>> +}
> 
>> @@ -700,7 +707,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,
>>  	 * check if it's already passed.  In short, we need a sample.
>>  	 */
>>  	if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
>> -		cpu_clock_sample(timer->it_clock, p, &val);
>> +		do_cpu_clock_sample(timer->it_clock, p, false, &val);
>>  	} else {
>>  		cpu_timer_sample_group(timer->it_clock, p, &val);
>>  	}
> 
> This would suggest:
> 
> static inline int cpu_timer_sample(const clockid_t which_clock, struct task_struct *p, union cpu_time_count *cpu)
> {
> 	return do_cpu_clock_sample(which_clock, p, false, cpu);
> }
> 
> That would preserve the: cpu_{timer,clock}_sample{,_group}() form.

Yeah, agreed.
And also, all timer function should use cpu_timer_sample() instead of cpu_clock_sample().
check_thread_timers() uses p->se.sum_exec_runtime without delta. This is consitency with
per-process timer. Thus, other functions (e.g. posix_cpu_timers_get) should also use the
same.

> 
>> @@ -749,7 +756,13 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,
>>  	}
>>  
>>  	if (new_expires.sched != 0 && !(flags & TIMER_ABSTIME)) {
>> -		cpu_time_add(timer->it_clock, &new_expires, val);
>> +		union cpu_time_count now;
>> +
>> +		if (CPUCLOCK_PERTHREAD(timer->it_clock))
>> +			cpu_clock_sample(timer->it_clock, p, &now);
>> +		else
>> +			cpu_clock_sample_group(timer->it_clock, p, &now);
> 
> This triggered a pattern match against earlier in this function; but they're
> different now; timer vs clock. So nothing to merge...

Not different, I think.
Relative timeout need to calculate "now + timeout" by definition.

But which time is "now"? 

Example, thread1 has 10ms sum_exec_runtime and 4ms delta and call timer_settime(4ms).
Old code calculate an expire is 10+4=14. New one calculate  10+4+4=18.

Which expire is correct? When using old one, timer will fire just after syscall. This
is posix violation. 

In the other words,

	sighandler(){
		t1 = clock_gettime()
	}

	t0 = clock_gettime()
	timer_settime(timeout);
	 ... wait to fire
	
	assert (t1 - t0 >= timeout)

This pseudo code must be true. it is snippest what glibc rt/tst-cputimer1 test and failed.




> So I don't mind the code changes, although its still not entirely clear to me
> what exact problem is fixed how; and thus the Changelog needs TLC.
> 


  reply	other threads:[~2013-04-29 17:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-29  6:26 [PATCH 1/2] posix-cpu-timers: fix acounting delta_exec twice kosaki.motohiro
2013-04-29  6:26 ` [PATCH 2/2] posix-cpu-timers: fix wrong timer initialization kosaki.motohiro
2013-04-29 10:36   ` Peter Zijlstra
2013-04-29 17:53     ` KOSAKI Motohiro [this message]
2013-04-29 18:53       ` KOSAKI Motohiro
2013-04-29 19:17 ` [BUGFIX PATCH 3/2] posix-cpu-timers: check_thread_timers() uses task_sched_runtime() KOSAKI Motohiro
2013-04-29 19:18 ` [PATCH 4/2] sched: task_sched_runtime introduce micro optimization KOSAKI Motohiro
2013-04-29 19:19 ` [PATCH 5/2] posix-cpu-timers: cleanup cpu_{clock,timer}_sample{,_group} KOSAKI Motohiro
2013-04-29 19:20 ` [PATCH 6/2] posix-cpu-timers: timer functions must use timer time instead of clock time 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=517EB3B4.6040702@gmail.com \
    --to=kosaki.motohiro@gmail.com \
    --cc=davem@davemloft.net \
    --cc=fweisbec@gmail.com \
    --cc=kosaki.motohiro@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=olivier@trillion01.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=schwidefsky@de.ibm.com \
    --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.