[v1] examples/vm_power_manager: fix overflowed return value

Message ID 20190426084415.3979-1-david.hunt@intel.com (mailing list archive)
State Rejected, archived
Headers
Series [v1] examples/vm_power_manager: fix overflowed return value |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Hunt, David April 26, 2019, 8:44 a.m. UTC
  Coverity complains about the return of a value that may
possibly overflow because of a multiply. Limit the value
so it cannot overflow.

Coverity issue: 337677
Fixes: 4b1a631b8a ("examples/vm_power: add oob monitoring functions")
CC: stable@dpdk.org
Signed-off-by: David Hunt <david.hunt@intel.com>
---
 examples/vm_power_manager/oob_monitor_x86.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
  

Comments

Burakov, Anatoly April 26, 2019, 10:29 a.m. UTC | #1
On 26-Apr-19 9:44 AM, David Hunt wrote:
> Coverity complains about the return of a value that may
> possibly overflow because of a multiply. Limit the value
> so it cannot overflow.
> 
> Coverity issue: 337677
> Fixes: 4b1a631b8a ("examples/vm_power: add oob monitoring functions")
> CC: stable@dpdk.org
> Signed-off-by: David Hunt <david.hunt@intel.com>
> ---
>   examples/vm_power_manager/oob_monitor_x86.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/examples/vm_power_manager/oob_monitor_x86.c b/examples/vm_power_manager/oob_monitor_x86.c
> index ebd96b205..2074eec1e 100644
> --- a/examples/vm_power_manager/oob_monitor_x86.c
> +++ b/examples/vm_power_manager/oob_monitor_x86.c
> @@ -99,7 +99,10 @@ apply_policy(int core)
>   		return -1.0;
>   	}
>   
> -	ratio = (float)miss_diff * (float)100 / (float)hits_diff;
> +	ratio = (float)miss_diff / (float)hits_diff;
> +	if (ratio > 1.0)
> +		ratio = 1.0;
> +	ratio *= 100.0f;

It should probably be the other way around - multiply first, then clamp. 
Also, please use RTE_MIN.

>   
>   	if (ratio < ci->branch_ratio_threshold)
>   		power_manager_scale_core_min(core);
>
  
Hunt, David April 26, 2019, 11:14 a.m. UTC | #2
Hi Anatoly,

On 26/4/2019 11:29 AM, Burakov, Anatoly wrote:
> On 26-Apr-19 9:44 AM, David Hunt wrote:
>> Coverity complains about the return of a value that may
>> possibly overflow because of a multiply. Limit the value
>> so it cannot overflow.
>>
>> Coverity issue: 337677
>> Fixes: 4b1a631b8a ("examples/vm_power: add oob monitoring functions")
>> CC: stable@dpdk.org
>> Signed-off-by: David Hunt <david.hunt@intel.com>
>> ---
>>   examples/vm_power_manager/oob_monitor_x86.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/examples/vm_power_manager/oob_monitor_x86.c 
>> b/examples/vm_power_manager/oob_monitor_x86.c
>> index ebd96b205..2074eec1e 100644
>> --- a/examples/vm_power_manager/oob_monitor_x86.c
>> +++ b/examples/vm_power_manager/oob_monitor_x86.c
>> @@ -99,7 +99,10 @@ apply_policy(int core)
>>           return -1.0;
>>       }
>>   -    ratio = (float)miss_diff * (float)100 / (float)hits_diff;
>> +    ratio = (float)miss_diff / (float)hits_diff;
>> +    if (ratio > 1.0)
>> +        ratio = 1.0;
>> +    ratio *= 100.0f;
>
> It should probably be the other way around - multiply first, then 
> clamp. Also, please use RTE_MIN.
>
I tried that, but coverity still sees an overflow condition. I need to 
clamp first, then multiply. Then coverity is happy.

Also, do you really want me to change to use RTE_MIN? I honestly prefer 
the code as it is.



>>         if (ratio < ci->branch_ratio_threshold)
>>           power_manager_scale_core_min(core);
>>
>
>
  
Burakov, Anatoly April 26, 2019, 12:03 p.m. UTC | #3
On 26-Apr-19 12:14 PM, Hunt, David wrote:
> Hi Anatoly,
> 
> On 26/4/2019 11:29 AM, Burakov, Anatoly wrote:
>> On 26-Apr-19 9:44 AM, David Hunt wrote:
>>> Coverity complains about the return of a value that may
>>> possibly overflow because of a multiply. Limit the value
>>> so it cannot overflow.
>>>
>>> Coverity issue: 337677
>>> Fixes: 4b1a631b8a ("examples/vm_power: add oob monitoring functions")
>>> CC: stable@dpdk.org
>>> Signed-off-by: David Hunt <david.hunt@intel.com>
>>> ---
>>>   examples/vm_power_manager/oob_monitor_x86.c | 5 ++++-
>>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/examples/vm_power_manager/oob_monitor_x86.c 
>>> b/examples/vm_power_manager/oob_monitor_x86.c
>>> index ebd96b205..2074eec1e 100644
>>> --- a/examples/vm_power_manager/oob_monitor_x86.c
>>> +++ b/examples/vm_power_manager/oob_monitor_x86.c
>>> @@ -99,7 +99,10 @@ apply_policy(int core)
>>>           return -1.0;
>>>       }
>>>   -    ratio = (float)miss_diff * (float)100 / (float)hits_diff;
>>> +    ratio = (float)miss_diff / (float)hits_diff;
>>> +    if (ratio > 1.0)
>>> +        ratio = 1.0;
>>> +    ratio *= 100.0f;
>>
>> It should probably be the other way around - multiply first, then 
>> clamp. Also, please use RTE_MIN.
>>
> I tried that, but coverity still sees an overflow condition. I need to 
> clamp first, then multiply. Then coverity is happy.

That's weird. This may be a bug in Coverity then. Please correct me if 
i'm wrong, but floating point formats aren't precise, so by doing 
multiplication on a value that doesn't exceed 1.0, you may very well end 
up with a value that does exceed 100 by a tiny bit on account of 
floating point approximations, rounding errors etc.

The question is, do we want correct code, or do we want to keep Coverity 
happy? :) I'll have a look at the coverity issue itself, maybe i'm 
missing something here...

> 
> Also, do you really want me to change to use RTE_MIN? I honestly prefer 
> the code as it is.

No strong opinion here.

> 
> 
> 
>>>         if (ratio < ci->branch_ratio_threshold)
>>>           power_manager_scale_core_min(core);
>>>
>>
>>
>
  
Burakov, Anatoly April 26, 2019, 12:35 p.m. UTC | #4
On 26-Apr-19 1:03 PM, Burakov, Anatoly wrote:
> On 26-Apr-19 12:14 PM, Hunt, David wrote:
>> Hi Anatoly,
>>
>> On 26/4/2019 11:29 AM, Burakov, Anatoly wrote:
>>> On 26-Apr-19 9:44 AM, David Hunt wrote:
>>>> Coverity complains about the return of a value that may
>>>> possibly overflow because of a multiply. Limit the value
>>>> so it cannot overflow.
>>>>
>>>> Coverity issue: 337677
>>>> Fixes: 4b1a631b8a ("examples/vm_power: add oob monitoring functions")
>>>> CC: stable@dpdk.org
>>>> Signed-off-by: David Hunt <david.hunt@intel.com>
>>>> ---
>>>>   examples/vm_power_manager/oob_monitor_x86.c | 5 ++++-
>>>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/examples/vm_power_manager/oob_monitor_x86.c 
>>>> b/examples/vm_power_manager/oob_monitor_x86.c
>>>> index ebd96b205..2074eec1e 100644
>>>> --- a/examples/vm_power_manager/oob_monitor_x86.c
>>>> +++ b/examples/vm_power_manager/oob_monitor_x86.c
>>>> @@ -99,7 +99,10 @@ apply_policy(int core)
>>>>           return -1.0;
>>>>       }
>>>>   -    ratio = (float)miss_diff * (float)100 / (float)hits_diff;
>>>> +    ratio = (float)miss_diff / (float)hits_diff;
>>>> +    if (ratio > 1.0)
>>>> +        ratio = 1.0;
>>>> +    ratio *= 100.0f;
>>>
>>> It should probably be the other way around - multiply first, then 
>>> clamp. Also, please use RTE_MIN.
>>>
>> I tried that, but coverity still sees an overflow condition. I need to 
>> clamp first, then multiply. Then coverity is happy.
> 
> That's weird. This may be a bug in Coverity then. Please correct me if 
> i'm wrong, but floating point formats aren't precise, so by doing 
> multiplication on a value that doesn't exceed 1.0, you may very well end 
> up with a value that does exceed 100 by a tiny bit on account of 
> floating point approximations, rounding errors etc.
> 
> The question is, do we want correct code, or do we want to keep Coverity 
> happy? :) I'll have a look at the coverity issue itself, maybe i'm 
> missing something here...
> 

I think the real source of the problem is not that, and i believe 
there's something wrong with Coverity's analysis here.

For some reason Coverity thinks that multiplying two floating point 
values (100f and miss_diff converted to float) will result in /integer/ 
overflow (lolwut?), *and* it assumes that miss_diff is negative at that 
point when it *can't* be, because if miss_diff was negative, we would've 
done an early exit on line 77.

My guess is, this is the culprit:

"overflow: Multiply operation overflows on operands (float)miss_diff and 
100f. Example values for operands: *100f = 268435456*, (float)miss_diff 
= -2147483648."

The "100f = 268435456" part makes me suspect that Coverity somehow 
thinks that "100f" is a variable name?

>>
>> Also, do you really want me to change to use RTE_MIN? I honestly 
>> prefer the code as it is.
> 
> No strong opinion here.
> 
>>
>>
>>
>>>>         if (ratio < ci->branch_ratio_threshold)
>>>>           power_manager_scale_core_min(core);
>>>>
>>>
>>>
>>
> 
>
  
Hunt, David April 26, 2019, 1:50 p.m. UTC | #5
On 26/4/2019 11:29 AM, Burakov, Anatoly wrote:
> On 26-Apr-19 9:44 AM, David Hunt wrote:
>> Coverity complains about the return of a value that may
>> possibly overflow because of a multiply. Limit the value
>> so it cannot overflow.
>>
>> Coverity issue: 337677
>> Fixes: 4b1a631b8a ("examples/vm_power: add oob monitoring functions")
>> CC: stable@dpdk.org
>> Signed-off-by: David Hunt <david.hunt@intel.com>
>> ---
>>   examples/vm_power_manager/oob_monitor_x86.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/examples/vm_power_manager/oob_monitor_x86.c 
>> b/examples/vm_power_manager/oob_monitor_x86.c
>> index ebd96b205..2074eec1e 100644
>> --- a/examples/vm_power_manager/oob_monitor_x86.c
>> +++ b/examples/vm_power_manager/oob_monitor_x86.c
>> @@ -99,7 +99,10 @@ apply_policy(int core)
>>           return -1.0;
>>       }
>>   -    ratio = (float)miss_diff * (float)100 / (float)hits_diff;
>> +    ratio = (float)miss_diff / (float)hits_diff;
>> +    if (ratio > 1.0)
>> +        ratio = 1.0;
>> +    ratio *= 100.0f;
>
> It should probably be the other way around - multiply first, then 
> clamp. Also, please use RTE_MIN.
>
>>         if (ratio < ci->branch_ratio_threshold)
>>           power_manager_scale_core_min(core);
>>

Anatoly and myself have spendt some time analysing the coverity issue 
just now, and we have come to the conclusion that it's a false positive. 
We also think it may be an issue with coverity, so for the moment I'll 
mark the coverity issue as a false positive.
  

Patch

diff --git a/examples/vm_power_manager/oob_monitor_x86.c b/examples/vm_power_manager/oob_monitor_x86.c
index ebd96b205..2074eec1e 100644
--- a/examples/vm_power_manager/oob_monitor_x86.c
+++ b/examples/vm_power_manager/oob_monitor_x86.c
@@ -99,7 +99,10 @@  apply_policy(int core)
 		return -1.0;
 	}
 
-	ratio = (float)miss_diff * (float)100 / (float)hits_diff;
+	ratio = (float)miss_diff / (float)hits_diff;
+	if (ratio > 1.0)
+		ratio = 1.0;
+	ratio *= 100.0f;
 
 	if (ratio < ci->branch_ratio_threshold)
 		power_manager_scale_core_min(core);