diff mbox

[1/2] linux-generic: odp_schedule: fix odp_schdule_wait_time

Message ID 1441878522-19505-2-git-send-email-ivan.khoronzhuk@linaro.org
State Superseded
Headers show

Commit Message

Ivan Khoronzhuk Sept. 10, 2015, 9:48 a.m. UTC
The resolution of schedule time can be more than 1ns. As result
can happen that 1ns corresponds 0 ticks of timer counter, but if
passed 1ns it's obvious that user wanted to schedule at least once.
Currently it can lead to wait forever, as 0 corresponds to
ODP_SCHED_WAIT, it can block program flow at all.

Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can
wait a little, when shced time has slower rate. It should correspond
to schedule only once.

So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX.

Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
 platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++--
 platform/linux-generic/odp_schedule.c                    | 3 ---
 2 files changed, 2 insertions(+), 5 deletions(-)

Comments

Ivan Khoronzhuk Sept. 10, 2015, 11:16 a.m. UTC | #1
Petri,

Are you OK with this change?

On 10.09.15 12:48, Ivan Khoronzhuk wrote:
> The resolution of schedule time can be more than 1ns. As result
> can happen that 1ns corresponds 0 ticks of timer counter, but if
> passed 1ns it's obvious that user wanted to schedule at least once.
> Currently it can lead to wait forever, as 0 corresponds to
> ODP_SCHED_WAIT, it can block program flow at all.
>
> Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can
> wait a little, when shced time has slower rate. It should correspond
> to schedule only once.
>
> So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX.
>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
> ---
>   platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++--
>   platform/linux-generic/odp_schedule.c                    | 3 ---
>   2 files changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h
> index c48b652..8cdc40b 100644
> --- a/platform/linux-generic/include/odp/plat/schedule_types.h
> +++ b/platform/linux-generic/include/odp/plat/schedule_types.h
> @@ -22,8 +22,8 @@ extern "C" {
>    *  @{
>    */
>
> -#define ODP_SCHED_WAIT     0
> -#define ODP_SCHED_NO_WAIT  1
> +#define ODP_SCHED_WAIT     UINT64_MAX
> +#define ODP_SCHED_NO_WAIT  0
>
>   typedef int odp_schedule_prio_t;
>
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
> index c6619e5..827fcf0 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -646,9 +646,6 @@ void odp_schedule_resume(void)
>
>   uint64_t odp_schedule_wait_time(uint64_t ns)
>   {
> -	if (ns <= ODP_SCHED_NO_WAIT)
> -		ns = ODP_SCHED_NO_WAIT + 1;
> -
>   	return odp_time_ns_to_cycles(ns);
>   }
>
>
Savolainen, Petri (Nokia - FI/Espoo) Sept. 10, 2015, 12:16 p.m. UTC | #2
Change is OK. The calculation can be changed to use cpu cycle API (with max CPU hz) later. Time measurement does not have to be accurate, so we can continue to use CPU cycles and max hz (to spin at least 'ns' nanosec).

The patch needs to be labeled with "v2". And preferably PATCH, in capital letters.

The log entry could be clarified a bit, see under.


> -----Original Message-----
> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
> Sent: Thursday, September 10, 2015 12:49 PM
> To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo);
> nmorey@kalray.eu
> Cc: Ivan Khoronzhuk
> Subject: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix
> odp_schdule_wait_time
> 
> The resolution of schedule time can be more than 1ns. As result
> can happen that 1ns corresponds 0 ticks of timer counter, but if
> passed 1ns it's obvious that user wanted to schedule at least once.

In short: "Depending on resolution, a low nsec value could be converted to 0 cycles, which was specified as WAIT ..."

> Currently it can lead to wait forever, as 0 corresponds to
> ODP_SCHED_WAIT, it can block program flow at all.

"... and would instruct a schedule call to wait forever."

-Petri


> 
> Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can
> wait a little, when shced time has slower rate. It should correspond
> to schedule only once.
> 
> So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX.
> 
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
> ---
>  platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++--
>  platform/linux-generic/odp_schedule.c                    | 3 ---
>  2 files changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h
> b/platform/linux-generic/include/odp/plat/schedule_types.h
> index c48b652..8cdc40b 100644
> --- a/platform/linux-generic/include/odp/plat/schedule_types.h
> +++ b/platform/linux-generic/include/odp/plat/schedule_types.h
> @@ -22,8 +22,8 @@ extern "C" {
>   *  @{
>   */
> 
> -#define ODP_SCHED_WAIT     0
> -#define ODP_SCHED_NO_WAIT  1
> +#define ODP_SCHED_WAIT     UINT64_MAX
> +#define ODP_SCHED_NO_WAIT  0
> 
>  typedef int odp_schedule_prio_t;
> 
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
> generic/odp_schedule.c
> index c6619e5..827fcf0 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -646,9 +646,6 @@ void odp_schedule_resume(void)
> 
>  uint64_t odp_schedule_wait_time(uint64_t ns)
>  {
> -	if (ns <= ODP_SCHED_NO_WAIT)
> -		ns = ODP_SCHED_NO_WAIT + 1;
> -
>  	return odp_time_ns_to_cycles(ns);
>  }
> 
> --
> 1.9.1
Ivan Khoronzhuk Sept. 10, 2015, 12:33 p.m. UTC | #3
On 10.09.15 15:16, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> Change is OK. The calculation can be changed to use cpu cycle API (with max CPU hz) later. Time measurement does not have to be accurate, so we can continue to use CPU cycles and max hz (to spin at least 'ns' nanosec).
We can wait more than 4s, with my cpu cycle counter it's not possible.
And don't forget about CPU freq and conversion to ns.
This is not place to write about that, lets talk about later.

>
> The patch needs to be labeled with "v2". And preferably PATCH, in capital letters.
It differs in numbering 1/2. I prefer to hold the same numbering within series.
But, next time I will bear it in mind.

>
> The log entry could be clarified a bit, see under.
>
>
>> -----Original Message-----
>> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
>> Sent: Thursday, September 10, 2015 12:49 PM
>> To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo);
>> nmorey@kalray.eu
>> Cc: Ivan Khoronzhuk
>> Subject: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix
>> odp_schdule_wait_time
>>
>> The resolution of schedule time can be more than 1ns. As result
>> can happen that 1ns corresponds 0 ticks of timer counter, but if
>> passed 1ns it's obvious that user wanted to schedule at least once.
>
> In short: "Depending on resolution, a low nsec value could be converted to 0 cycles, which was specified as WAIT ..."

Ok

>
>> Currently it can lead to wait forever, as 0 corresponds to
>> ODP_SCHED_WAIT, it can block program flow at all.
>
> "... and would instruct a schedule call to wait forever."

Ok

>
>
>>
>> Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can
>> wait a little, when shced time has slower rate. It should correspond
>> to schedule only once.
>>
>> So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to UINT64_MAX.
>>
>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>> ---
>>   platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++--
>>   platform/linux-generic/odp_schedule.c                    | 3 ---
>>   2 files changed, 2 insertions(+), 5 deletions(-)
>>
>> diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h
>> b/platform/linux-generic/include/odp/plat/schedule_types.h
>> index c48b652..8cdc40b 100644
>> --- a/platform/linux-generic/include/odp/plat/schedule_types.h
>> +++ b/platform/linux-generic/include/odp/plat/schedule_types.h
>> @@ -22,8 +22,8 @@ extern "C" {
>>    *  @{
>>    */
>>
>> -#define ODP_SCHED_WAIT     0
>> -#define ODP_SCHED_NO_WAIT  1
>> +#define ODP_SCHED_WAIT     UINT64_MAX
>> +#define ODP_SCHED_NO_WAIT  0
>>
>>   typedef int odp_schedule_prio_t;
>>
>> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
>> generic/odp_schedule.c
>> index c6619e5..827fcf0 100644
>> --- a/platform/linux-generic/odp_schedule.c
>> +++ b/platform/linux-generic/odp_schedule.c
>> @@ -646,9 +646,6 @@ void odp_schedule_resume(void)
>>
>>   uint64_t odp_schedule_wait_time(uint64_t ns)
>>   {
>> -	if (ns <= ODP_SCHED_NO_WAIT)
>> -		ns = ODP_SCHED_NO_WAIT + 1;
>> -
>>   	return odp_time_ns_to_cycles(ns);
>>   }
>>
>> --
>> 1.9.1
>
>
>
>
>
>
Savolainen, Petri (Nokia - FI/Espoo) Sept. 10, 2015, 1:03 p.m. UTC | #4
> -----Original Message-----
> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
> Sent: Thursday, September 10, 2015 3:34 PM
> To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org;
> nmorey@kalray.eu
> Subject: Re: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix
> odp_schdule_wait_time
> 
> 
> 
> On 10.09.15 15:16, Savolainen, Petri (Nokia - FI/Espoo) wrote:
> > Change is OK. The calculation can be changed to use cpu cycle API
> (with max CPU hz) later. Time measurement does not have to be accurate,
> so we can continue to use CPU cycles and max hz (to spin at least 'ns'
> nanosec).
> We can wait more than 4s, with my cpu cycle counter it's not possible.
> And don't forget about CPU freq and conversion to ns.
> This is not place to write about that, lets talk about later.

With scheduler you can wait more than 4 sec, since your implementation does the spinning and it can be sure that counter is not wrapping (you'll check the counter every 30 cycles or so while waiting).

When you know the max freq (e.g. 1GHz) and calculate how many CPU cycles you need to spin based on that, you'll always wait at least the time requested. CPU can run slower than max (e.g. 500MHz), which means that you may wait longer than 'ns' nanoseconds, but it's OK according the spec. You did wait "at least" 'ns' nsec (e.g. 2x ns).

-Petri


> 
> >
> > The patch needs to be labeled with "v2". And preferably PATCH, in
> capital letters.
> It differs in numbering 1/2. I prefer to hold the same numbering within
> series.
> But, next time I will bear it in mind.
> 
> >
> > The log entry could be clarified a bit, see under.
> >
> >
> >> -----Original Message-----
> >> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
> >> Sent: Thursday, September 10, 2015 12:49 PM
> >> To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo);
> >> nmorey@kalray.eu
> >> Cc: Ivan Khoronzhuk
> >> Subject: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix
> >> odp_schdule_wait_time
> >>
> >> The resolution of schedule time can be more than 1ns. As result
> >> can happen that 1ns corresponds 0 ticks of timer counter, but if
> >> passed 1ns it's obvious that user wanted to schedule at least once.
> >
> > In short: "Depending on resolution, a low nsec value could be
> converted to 0 cycles, which was specified as WAIT ..."
> 
> Ok
> 
> >
> >> Currently it can lead to wait forever, as 0 corresponds to
> >> ODP_SCHED_WAIT, it can block program flow at all.
> >
> > "... and would instruct a schedule call to wait forever."
> 
> Ok
> 
> >
> >
> >>
> >> Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can
> >> wait a little, when shced time has slower rate. It should correspond
> >> to schedule only once.
> >>
> >> So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to
> UINT64_MAX.
> >>
> >> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
> >> ---
> >>   platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++--
> >>   platform/linux-generic/odp_schedule.c                    | 3 ---
> >>   2 files changed, 2 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/platform/linux-
> generic/include/odp/plat/schedule_types.h
> >> b/platform/linux-generic/include/odp/plat/schedule_types.h
> >> index c48b652..8cdc40b 100644
> >> --- a/platform/linux-generic/include/odp/plat/schedule_types.h
> >> +++ b/platform/linux-generic/include/odp/plat/schedule_types.h
> >> @@ -22,8 +22,8 @@ extern "C" {
> >>    *  @{
> >>    */
> >>
> >> -#define ODP_SCHED_WAIT     0
> >> -#define ODP_SCHED_NO_WAIT  1
> >> +#define ODP_SCHED_WAIT     UINT64_MAX
> >> +#define ODP_SCHED_NO_WAIT  0
> >>
> >>   typedef int odp_schedule_prio_t;
> >>
> >> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
> >> generic/odp_schedule.c
> >> index c6619e5..827fcf0 100644
> >> --- a/platform/linux-generic/odp_schedule.c
> >> +++ b/platform/linux-generic/odp_schedule.c
> >> @@ -646,9 +646,6 @@ void odp_schedule_resume(void)
> >>
> >>   uint64_t odp_schedule_wait_time(uint64_t ns)
> >>   {
> >> -	if (ns <= ODP_SCHED_NO_WAIT)
> >> -		ns = ODP_SCHED_NO_WAIT + 1;
> >> -
> >>   	return odp_time_ns_to_cycles(ns);
> >>   }
> >>
> >> --
> >> 1.9.1
> >
> >
> >
> >
> >
> >
> 
> --
> Regards,
> Ivan Khoronzhuk
Ivan Khoronzhuk Sept. 10, 2015, 1:15 p.m. UTC | #5
On 10.09.15 16:03, Savolainen, Petri (Nokia - FI/Espoo) wrote:
>
>
>> -----Original Message-----
>> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
>> Sent: Thursday, September 10, 2015 3:34 PM
>> To: Savolainen, Petri (Nokia - FI/Espoo); lng-odp@lists.linaro.org;
>> nmorey@kalray.eu
>> Subject: Re: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix
>> odp_schdule_wait_time
>>
>>
>>
>> On 10.09.15 15:16, Savolainen, Petri (Nokia - FI/Espoo) wrote:
>>> Change is OK. The calculation can be changed to use cpu cycle API
>> (with max CPU hz) later. Time measurement does not have to be accurate,
>> so we can continue to use CPU cycles and max hz (to spin at least 'ns'
>> nanosec).
>> We can wait more than 4s, with my cpu cycle counter it's not possible.
>> And don't forget about CPU freq and conversion to ns.
>> This is not place to write about that, lets talk about later.
>
> With scheduler you can wait more than 4 sec, since your implementation does the spinning and it can be sure
> that counter is not wrapping (you'll check the counter every 30 cycles or so while waiting).

Ok.

>
> When you know the max freq (e.g. 1GHz) and calculate how many CPU cycles you need to spin
> based on that, you'll always wait at least the time requested. CPU can run slower than max (e.g. 500MHz),
> which means that you may wait longer than 'ns' nanoseconds, but it's OK according the spec.
> You did wait "at least" 'ns' nsec (e.g. 2x ns).

2x can have much bigger delay error than time API produces.
Especially when bigger delay is requested, say 50 ns, and you wait ~100ns.
In most cases I suppose rate of counter ~ 3 time less than Fmax.
Lets take 7ns time resolution,  then 50ns + 7ns = 57ns.
error: 7ns << 50ns.

And for linux-generic cpu_cycles are only one source of counter.
It's reused by time API, so here cpu cycles anyway.

>
> -Petri
>
>
>>
>>>
>>> The patch needs to be labeled with "v2". And preferably PATCH, in
>> capital letters.
>> It differs in numbering 1/2. I prefer to hold the same numbering within
>> series.
>> But, next time I will bear it in mind.
>>
>>>
>>> The log entry could be clarified a bit, see under.
>>>
>>>
>>>> -----Original Message-----
>>>> From: EXT Ivan Khoronzhuk [mailto:ivan.khoronzhuk@linaro.org]
>>>> Sent: Thursday, September 10, 2015 12:49 PM
>>>> To: lng-odp@lists.linaro.org; Savolainen, Petri (Nokia - FI/Espoo);
>>>> nmorey@kalray.eu
>>>> Cc: Ivan Khoronzhuk
>>>> Subject: [lng-odp] [Patch 1/2] linux-generic: odp_schedule: fix
>>>> odp_schdule_wait_time
>>>>
>>>> The resolution of schedule time can be more than 1ns. As result
>>>> can happen that 1ns corresponds 0 ticks of timer counter, but if
>>>> passed 1ns it's obvious that user wanted to schedule at least once.
>>>
>>> In short: "Depending on resolution, a low nsec value could be
>> converted to 0 cycles, which was specified as WAIT ..."
>>
>> Ok
>>
>>>
>>>> Currently it can lead to wait forever, as 0 corresponds to
>>>> ODP_SCHED_WAIT, it can block program flow at all.
>>>
>>> "... and would instruct a schedule call to wait forever."
>>
>> Ok
>>
>>>
>>>
>>>>
>>>> Also ODP_SCHED_NO_WAIT corresponds to 1 tick, it's rarely but can
>>>> wait a little, when shced time has slower rate. It should correspond
>>>> to schedule only once.
>>>>
>>>> So, change ODP_SCHED_NO_WAIT to 0 and ODP_SCHED_NO_WAIT to
>> UINT64_MAX.
>>>>
>>>> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
>>>> ---
>>>>    platform/linux-generic/include/odp/plat/schedule_types.h | 4 ++--
>>>>    platform/linux-generic/odp_schedule.c                    | 3 ---
>>>>    2 files changed, 2 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/platform/linux-
>> generic/include/odp/plat/schedule_types.h
>>>> b/platform/linux-generic/include/odp/plat/schedule_types.h
>>>> index c48b652..8cdc40b 100644
>>>> --- a/platform/linux-generic/include/odp/plat/schedule_types.h
>>>> +++ b/platform/linux-generic/include/odp/plat/schedule_types.h
>>>> @@ -22,8 +22,8 @@ extern "C" {
>>>>     *  @{
>>>>     */
>>>>
>>>> -#define ODP_SCHED_WAIT     0
>>>> -#define ODP_SCHED_NO_WAIT  1
>>>> +#define ODP_SCHED_WAIT     UINT64_MAX
>>>> +#define ODP_SCHED_NO_WAIT  0
>>>>
>>>>    typedef int odp_schedule_prio_t;
>>>>
>>>> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-
>>>> generic/odp_schedule.c
>>>> index c6619e5..827fcf0 100644
>>>> --- a/platform/linux-generic/odp_schedule.c
>>>> +++ b/platform/linux-generic/odp_schedule.c
>>>> @@ -646,9 +646,6 @@ void odp_schedule_resume(void)
>>>>
>>>>    uint64_t odp_schedule_wait_time(uint64_t ns)
>>>>    {
>>>> -	if (ns <= ODP_SCHED_NO_WAIT)
>>>> -		ns = ODP_SCHED_NO_WAIT + 1;
>>>> -
>>>>    	return odp_time_ns_to_cycles(ns);
>>>>    }
>>>>
>>>> --
>>>> 1.9.1
>>>
>>>
>>>
>>>
>>>
>>>
>>
>> --
>> Regards,
>> Ivan Khoronzhuk
diff mbox

Patch

diff --git a/platform/linux-generic/include/odp/plat/schedule_types.h b/platform/linux-generic/include/odp/plat/schedule_types.h
index c48b652..8cdc40b 100644
--- a/platform/linux-generic/include/odp/plat/schedule_types.h
+++ b/platform/linux-generic/include/odp/plat/schedule_types.h
@@ -22,8 +22,8 @@  extern "C" {
  *  @{
  */
 
-#define ODP_SCHED_WAIT     0
-#define ODP_SCHED_NO_WAIT  1
+#define ODP_SCHED_WAIT     UINT64_MAX
+#define ODP_SCHED_NO_WAIT  0
 
 typedef int odp_schedule_prio_t;
 
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index c6619e5..827fcf0 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -646,9 +646,6 @@  void odp_schedule_resume(void)
 
 uint64_t odp_schedule_wait_time(uint64_t ns)
 {
-	if (ns <= ODP_SCHED_NO_WAIT)
-		ns = ODP_SCHED_NO_WAIT + 1;
-
 	return odp_time_ns_to_cycles(ns);
 }