diff mbox

[2/2] cpufreq: ondemand: Eliminate the deadband effect

Message ID 1404147574-17422-3-git-send-email-stratosk@semaphore.gr (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Stratos Karafotis June 30, 2014, 4:59 p.m. UTC
Currently, ondemand calculates the target frequency proportional to load
using the formula:
	Target frequency = C * load
	where C = policy->cpuinfo.max_freq / 100

Though, in many cases, the minimum available frequency is pretty high and
the above calculation introduces a dead band from load 0 to
100 * policy->cpuinfo.min_freq / policy->cpuinfo.max_freq where the target
frequency is always calculated to less than policy->cpuinfo.min_freq and
the minimum frequency is selected.

For example: on Intel i7-3770 @ 3.4GHz the policy->cpuinfo.min_freq = 1600000
and the policy->cpuinfo.max_freq = 3400000 (without turbo). Thus, the CPU
starts to scale up at a load above 47.
On quad core 1500MHz Krait the policy->cpuinfo.min_freq = 384000
and the policy->cpuinfo.max_freq = 1512000. Thus, the CPU starts to scale
at load above 25.

Change the calculation of target frequency to eliminate the above effect using
the formula:

	Target frequency = A + B * load
	where A = policy->cpuinfo.min_freq and
	      B = (policy->cpuinfo.max_freq - policy->cpuinfo->min_freq) / 100

This will map load values 0 to 100 linearly to cpuinfo.min_freq to
cpuinfo.max_freq.

Also, use the CPUFREQ_RELATION_C in __cpufreq_driver_target to select the
closest frequency in frequency_table. This is necessary to avoid selection
of minimum frequency only when load equals to 0. It will also help for selection
of frequencies using a more 'fair' criterion.

Tables below show the difference in selected frequency for specific values
of load without and with this patch. On Intel i7-3770 @ 3.40GHz:
	Without			With
Load	Target	Selected	Target	Selected
0	0	1600000		1600000	1600000
5	170050	1600000		1690050	1700000
10	340100	1600000		1780100	1700000
15	510150	1600000		1870150	1900000
20	680200	1600000		1960200	2000000
25	850250	1600000		2050250	2100000
30	1020300	1600000		2140300	2100000
35	1190350	1600000		2230350	2200000
40	1360400	1600000		2320400	2400000
45	1530450	1600000		2410450	2400000
50	1700500	1900000		2500500	2500000
55	1870550	1900000		2590550	2600000
60	2040600	2100000		2680600	2600000
65	2210650	2400000		2770650	2800000
70	2380700	2400000		2860700	2800000
75	2550750	2600000		2950750	3000000
80	2720800	2800000		3040800	3000000
85	2890850	2900000		3130850	3100000
90	3060900	3100000		3220900	3300000
95	3230950	3300000		3310950	3300000
100	3401000	3401000		3401000	3401000

On ARM quad core 1500MHz Krait:
	Without			With
Load	Target	Selected	Target	Selected
0	0	384000		384000	384000
5	75600	384000		440400	486000
10	151200	384000		496800	486000
15	226800	384000		553200	594000
20	302400	384000		609600	594000
25	378000	384000		666000	702000
30	453600	486000		722400	702000
35	529200	594000		778800	810000
40	604800	702000		835200	810000
45	680400	702000		891600	918000
50	756000	810000		948000	918000
55	831600	918000		1004400	1026000
60	907200	918000		1060800	1026000
65	982800	1026000		1117200	1134000
70	1058400	1134000		1173600	1134000
75	1134000	1134000		1230000	1242000
80	1209600	1242000		1286400	1242000
85	1285200	1350000		1342800	1350000
90	1360800	1458000		1399200	1350000
95	1436400	1458000		1455600	1458000
100	1512000	1512000		1512000	1512000

Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
(Android smartphone).
Benchmarks on Intel i7 shows a performance improvement on low and medium
work loads with lower power consumption. Specifics:

Phoronix Linux Kernel Compilation 3.1:
Time: -0.40%, energy: -0.07%
Phoronix Apache:
Time: -4.98%, energy: -2.35%
Phoronix FFMPEG:
Time: -6.29%, energy: -4.02%

Also, running mp3 decoding (very low load) shows no differences with and
without this patch.

Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
---
 drivers/cpufreq/cpufreq_ondemand.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

Comments

Pavel Machek July 11, 2014, 4:57 p.m. UTC | #1
Hi!

> Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
> (Android smartphone).
> Benchmarks on Intel i7 shows a performance improvement on low and medium
> work loads with lower power consumption. Specifics:
> 
> Phoronix Linux Kernel Compilation 3.1:
> Time: -0.40%, energy: -0.07%
> Phoronix Apache:
> Time: -4.98%, energy: -2.35%
> Phoronix FFMPEG:
> Time: -6.29%, energy: -4.02%

Hmm. Intel i7 should be race-to-idle machine. So basically rule like
if (load > 0) go to max frequency else go to lowest frequency would do
the right thing in your test, right?

So... should we do that, or do we need better benchmark?
									Pavel
Stratos Karafotis July 11, 2014, 5:29 p.m. UTC | #2
Hi Pavel!

On 11/07/2014 07:57 ??, Pavel Machek wrote:
> Hi!
> 
>> Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
>> (Android smartphone).
>> Benchmarks on Intel i7 shows a performance improvement on low and medium
>> work loads with lower power consumption. Specifics:
>>
>> Phoronix Linux Kernel Compilation 3.1:
>> Time: -0.40%, energy: -0.07%
>> Phoronix Apache:
>> Time: -4.98%, energy: -2.35%
>> Phoronix FFMPEG:
>> Time: -6.29%, energy: -4.02%
> 
> Hmm. Intel i7 should be race-to-idle machine. So basically rule like
> if (load > 0) go to max frequency else go to lowest frequency would do
> the right thing in your test, right?

I don't think that "if (load > 0) go to max" will work even on i7.
For low load this will have impact on energy consumption.
On my tests, a simple mp3 decoding (very low load on my machine) have no
difference with and without this patch.

> So... should we do that, or do we need better benchmark?

I'm sorry. I'm not sure I understood exactly what do you mean by "better
benchmark".
Of course, we should do as many benchmarks as we can.
I usually do these 5 sets of benchmarks on my i7 that IMHO give a good
indication about the changes in different CPU loads.

1) Linux kernel compilation (about 85% busy CPU)
2) Apache (about 32% busy CPU)
3) ffmpeg (about 24% busy CPU)
4) mp3 decoding (about 0.3% CPU)
5) Idle system (about 0.06% CPU)

The patch was also tested on a Android smartphone (kernel 3.4). The kernel
distributed to 1000+ users.
Unfortunately I have no benchmarks, but no regressions reported on
consumption. Actually, there reports for better performance and
lower power consumption, but of course we can't rely on these reports. :)


Thanks for your comments!

Stratos


--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek July 11, 2014, 6:34 p.m. UTC | #3
On Fri 2014-07-11 20:29:57, Stratos Karafotis wrote:
> Hi Pavel!
> 
> On 11/07/2014 07:57 ??, Pavel Machek wrote:
> > Hi!
> > 
> >> Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
> >> (Android smartphone).
> >> Benchmarks on Intel i7 shows a performance improvement on low and medium
> >> work loads with lower power consumption. Specifics:
> >>
> >> Phoronix Linux Kernel Compilation 3.1:
> >> Time: -0.40%, energy: -0.07%
> >> Phoronix Apache:
> >> Time: -4.98%, energy: -2.35%
> >> Phoronix FFMPEG:
> >> Time: -6.29%, energy: -4.02%
> > 
> > Hmm. Intel i7 should be race-to-idle machine. So basically rule like
> > if (load > 0) go to max frequency else go to lowest frequency would do
> > the right thing in your test, right?
> 
> I don't think that "if (load > 0) go to max" will work even on i7.
> For low load this will have impact on energy consumption.

Are you sure? CPU frequency should not matter on idle CPU.

(Can you try to modify your code and rerun for example the apache
test?)

> > So... should we do that, or do we need better benchmark?
> 
> I'm sorry. I'm not sure I understood exactly what do you mean by "better
> benchmark".

I believe that any increase of frequency in frequency will make the
benchmarks you qouted better (on i7). Actually, you can probably just
select performance governor...?

									Pavel
Stratos Karafotis July 11, 2014, 7:37 p.m. UTC | #4
On 11/07/2014 09:34 ??, Pavel Machek wrote:
> On Fri 2014-07-11 20:29:57, Stratos Karafotis wrote:
>> Hi Pavel!
>>
>> On 11/07/2014 07:57 ??, Pavel Machek wrote:
>>> Hi!
>>>
>>>> Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
>>>> (Android smartphone).
>>>> Benchmarks on Intel i7 shows a performance improvement on low and medium
>>>> work loads with lower power consumption. Specifics:
>>>>
>>>> Phoronix Linux Kernel Compilation 3.1:
>>>> Time: -0.40%, energy: -0.07%
>>>> Phoronix Apache:
>>>> Time: -4.98%, energy: -2.35%
>>>> Phoronix FFMPEG:
>>>> Time: -6.29%, energy: -4.02%
>>>
>>> Hmm. Intel i7 should be race-to-idle machine. So basically rule like
>>> if (load > 0) go to max frequency else go to lowest frequency would do
>>> the right thing in your test, right?
>>
>> I don't think that "if (load > 0) go to max" will work even on i7.
>> For low load this will have impact on energy consumption.
> 
> Are you sure? CPU frequency should not matter on idle CPU.

Even on a totally idle CPU there will be a small impact because of leakage
current (thanks to Dirk Brandewie for this info).

This simple test on a nearly idle system shows this:

[root@albert cpufreq]# for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n performance > $CPUFREQ; done
[root@albert cpufreq]# /home/stratosk/kernels/linux-pm/tools/power/x86/turbostat/turbostat -J sleep 20
    Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7   Pkg_J   Cor_J   GFX_J   time
       -       -       2    0.06    2712    3392       0    0.30    0.00   99.63    0.00      34      34    8.09    0.00   81.94    0.00  380.41   14.51    1.64   20.00
       0       0       0    0.02    1891    3392       0    0.09    0.00   99.88    0.00      34      34    8.09    0.00   81.94    0.00  380.41   14.51    1.64   20.00
       0       4       1    0.04    3006    3392       0    0.07
       1       1       1    0.04    2501    3392       0    0.62    0.00   99.33    0.00      34
       1       5       0    0.01    2346    3392       0    0.66
       2       2       0    0.01    1996    3392       0    0.44    0.00   99.55    0.00      34
       2       6       4    0.18    2278    3392       0    0.26
       3       3       5    0.15    3449    3392       0    0.07    0.01   99.77    0.00      34
       3       7       0    0.01    1839    3392       0    0.21
20.000899 sec
[root@albert cpufreq]# ^C
[root@albert cpufreq]# for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n ondemand > $CPUFREQ; done
[root@albert cpufreq]# /home/stratosk/kernels/linux-pm/tools/power/x86/turbostat/turbostat -J sleep 20
    Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7   Pkg_J   Cor_J   GFX_J   time
       -       -       2    0.09    1693    3392       0    0.35    0.01   99.55    0.00      35      36    8.33    0.00   84.31    0.00  377.68   12.23    1.15   20.00
       0       0       1    0.08    1603    3392       0    0.13    0.00   99.79    0.00      35      36    8.33    0.00   84.31    0.00  377.68   12.23    1.15   20.00
       0       4       1    0.08    1646    3392       0    0.13
       1       1       1    0.06    1647    3392       0    0.66    0.00   99.28    0.00      35
       1       5       0    0.01    1611    3392       0    0.71
       2       2       0    0.02    1617    3392       0    0.50    0.02   99.46    0.00      35
       2       6       4    0.22    1764    3392       0    0.30
       3       3       4    0.25    1701    3392       0    0.07    0.00   99.68    0.00      35
       3       7       0    0.01    1602    3392       0    0.31
20.001580 sec


So, for low loads the impact will be higher.
This is the reason that the intel_pstate driver don't use 'performance'
and try to request a low P state when there is no load.

> (Can you try to modify your code and rerun for example the apache
> test?)

Yes, I can do the apache test if the above example is not enough.

>>> So... should we do that, or do we need better benchmark?
>>
>> I'm sorry. I'm not sure I understood exactly what do you mean by "better
>> benchmark".
> 
> I believe that any increase of frequency in frequency will make the
> benchmarks you qouted better (on i7). Actually, you can probably just
> select performance governor...?

Maybe in benchmarks where the CPU load is high. But definitely not, in mp3
decoding and idle system test.

The point is, as you mentioned, more tests and of course on other CPUs.
Unfortunately, I can test only on i7 and krait as mentioned in changelog.
I will happily run any test you would like for more info.


Thanks,
Stratos
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pavel Machek July 20, 2014, 9:51 p.m. UTC | #5
Hi!

> >>>> Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
> >>>> (Android smartphone).
> >>>> Benchmarks on Intel i7 shows a performance improvement on low and medium
> >>>> work loads with lower power consumption. Specifics:
> >>>>
> >>>> Phoronix Linux Kernel Compilation 3.1:
> >>>> Time: -0.40%, energy: -0.07%
> >>>> Phoronix Apache:
> >>>> Time: -4.98%, energy: -2.35%
> >>>> Phoronix FFMPEG:
> >>>> Time: -6.29%, energy: -4.02%
> >>>
> >>> Hmm. Intel i7 should be race-to-idle machine. So basically rule like
> >>> if (load > 0) go to max frequency else go to lowest frequency would do
> >>> the right thing in your test, right?
> >>
> >> I don't think that "if (load > 0) go to max" will work even on i7.
> >> For low load this will have impact on energy consumption.
> > 
> > Are you sure? CPU frequency should not matter on idle CPU.
> 
> Even on a totally idle CPU there will be a small impact because of leakage
> current (thanks to Dirk Brandewie for this info).

Are you sure? IIRC Intel cpus will automatically lower CPU frequency
in deep C states..

> This simple test on a nearly idle system shows this:
> 
> [root@albert cpufreq]# for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n performance > $CPUFREQ; done
> [root@albert cpufreq]# /home/stratosk/kernels/linux-pm/tools/power/x86/turbostat/turbostat -J sleep 20
>     Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7   Pkg_J   Cor_J   GFX_J   time
>        -       -       2    0.06    2712    3392       0    0.30    0.00   99.63    0.00      34      34    8.09    0.00   81.94    0.00  380.41   14.51    1.64   20.00
>        0       0       0    0.02    1891    3392       0    0.09    0.00   99.88    0.00      34      34    8.09    0.00   81.94    0.00  380.41   14.51    1.64   20.00
>        0       4       1    0.04    3006    3392       0    0.07
>        1       1       1    0.04    2501    3392       0    0.62    0.00   99.33    0.00      34
>        1       5       0    0.01    2346    3392       0    0.66
>        2       2       0    0.01    1996    3392       0    0.44    0.00   99.55    0.00      34
>        2       6       4    0.18    2278    3392       0    0.26
>        3       3       5    0.15    3449    3392       0    0.07    0.01   99.77    0.00      34
>        3       7       0    0.01    1839    3392       0    0.21
> 20.000899 sec
> [root@albert cpufreq]# ^C
> [root@albert cpufreq]# for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n ondemand > $CPUFREQ; done
> [root@albert cpufreq]# /home/stratosk/kernels/linux-pm/tools/power/x86/turbostat/turbostat -J sleep 20
>     Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7   Pkg_J   Cor_J   GFX_J   time
>        -       -       2    0.09    1693    3392       0    0.35    0.01   99.55    0.00      35      36    8.33    0.00   84.31    0.00  377.68   12.23    1.15   20.00
>        0       0       1    0.08    1603    3392       0    0.13    0.00   99.79    0.00      35      36    8.33    0.00   84.31    0.00  377.68   12.23    1.15   20.00
>        0       4       1    0.08    1646    3392       0    0.13
>        1       1       1    0.06    1647    3392       0    0.66    0.00   99.28    0.00      35
>        1       5       0    0.01    1611    3392       0    0.71
>        2       2       0    0.02    1617    3392       0    0.50    0.02   99.46    0.00      35
>        2       6       4    0.22    1764    3392       0    0.30
>        3       3       4    0.25    1701    3392       0    0.07    0.00   99.68    0.00      35
>        3       7       0    0.01    1602    3392       0    0.31
> 20.001580 sec
> 
> 
> So, for low loads the impact will be higher.

So it seems ondemand saves cca 1% of energy?

Best regards,
									Pavel
Stratos Karafotis July 21, 2014, 5:41 a.m. UTC | #6
On 21/07/2014 12:51 ??, Pavel Machek wrote:
> Hi!
> 
>>>>>> Tested on Intel i7-3770 CPU @ 3.40GHz and on ARM quad core 1500MHz Krait
>>>>>> (Android smartphone).
>>>>>> Benchmarks on Intel i7 shows a performance improvement on low and medium
>>>>>> work loads with lower power consumption. Specifics:
>>>>>>
>>>>>> Phoronix Linux Kernel Compilation 3.1:
>>>>>> Time: -0.40%, energy: -0.07%
>>>>>> Phoronix Apache:
>>>>>> Time: -4.98%, energy: -2.35%
>>>>>> Phoronix FFMPEG:
>>>>>> Time: -6.29%, energy: -4.02%
>>>>>
>>>>> Hmm. Intel i7 should be race-to-idle machine. So basically rule like
>>>>> if (load > 0) go to max frequency else go to lowest frequency would do
>>>>> the right thing in your test, right?
>>>>
>>>> I don't think that "if (load > 0) go to max" will work even on i7.
>>>> For low load this will have impact on energy consumption.
>>>
>>> Are you sure? CPU frequency should not matter on idle CPU.
>>
>> Even on a totally idle CPU there will be a small impact because of leakage
>> current (thanks to Dirk Brandewie for this info).
> 
> Are you sure? IIRC Intel cpus will automatically lower CPU frequency
> in deep C states..

I'm sorry. I don't know further details about the leakage current
in deeper C states.

>> This simple test on a nearly idle system shows this:
>>
>> [root@albert cpufreq]# for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n performance > $CPUFREQ; done
>> [root@albert cpufreq]# /home/stratosk/kernels/linux-pm/tools/power/x86/turbostat/turbostat -J sleep 20
>>     Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7   Pkg_J   Cor_J   GFX_J   time
>>        -       -       2    0.06    2712    3392       0    0.30    0.00   99.63    0.00      34      34    8.09    0.00   81.94    0.00  380.41   14.51    1.64   20.00
>>        0       0       0    0.02    1891    3392       0    0.09    0.00   99.88    0.00      34      34    8.09    0.00   81.94    0.00  380.41   14.51    1.64   20.00
>>        0       4       1    0.04    3006    3392       0    0.07
>>        1       1       1    0.04    2501    3392       0    0.62    0.00   99.33    0.00      34
>>        1       5       0    0.01    2346    3392       0    0.66
>>        2       2       0    0.01    1996    3392       0    0.44    0.00   99.55    0.00      34
>>        2       6       4    0.18    2278    3392       0    0.26
>>        3       3       5    0.15    3449    3392       0    0.07    0.01   99.77    0.00      34
>>        3       7       0    0.01    1839    3392       0    0.21
>> 20.000899 sec
>> [root@albert cpufreq]# ^C
>> [root@albert cpufreq]# for CPUFREQ in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do [ -f $CPUFREQ ] || continue; echo -n ondemand > $CPUFREQ; done
>> [root@albert cpufreq]# /home/stratosk/kernels/linux-pm/tools/power/x86/turbostat/turbostat -J sleep 20
>>     Core     CPU Avg_MHz   %Busy Bzy_MHz TSC_MHz     SMI  CPU%c1  CPU%c3  CPU%c6  CPU%c7 CoreTmp  PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7   Pkg_J   Cor_J   GFX_J   time
>>        -       -       2    0.09    1693    3392       0    0.35    0.01   99.55    0.00      35      36    8.33    0.00   84.31    0.00  377.68   12.23    1.15   20.00
>>        0       0       1    0.08    1603    3392       0    0.13    0.00   99.79    0.00      35      36    8.33    0.00   84.31    0.00  377.68   12.23    1.15   20.00
>>        0       4       1    0.08    1646    3392       0    0.13
>>        1       1       1    0.06    1647    3392       0    0.66    0.00   99.28    0.00      35
>>        1       5       0    0.01    1611    3392       0    0.71
>>        2       2       0    0.02    1617    3392       0    0.50    0.02   99.46    0.00      35
>>        2       6       4    0.22    1764    3392       0    0.30
>>        3       3       4    0.25    1701    3392       0    0.07    0.00   99.68    0.00      35
>>        3       7       0    0.01    1602    3392       0    0.31
>> 20.001580 sec
>>
>>
>> So, for low loads the impact will be higher.
> 
> So it seems ondemand saves cca 1% of energy?

Yes, in this small test, on my nearly "idle" system.


Stratos
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 18d4091..ad3f38f 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -170,21 +170,24 @@  static void od_check_cpu(int cpu, unsigned int load)
 		dbs_freq_increase(policy, policy->max);
 	} else {
 		/* Calculate the next frequency proportional to load */
-		unsigned int freq_next;
-		freq_next = load * policy->cpuinfo.max_freq / 100;
+		unsigned int freq_next, min_f, max_f;
+
+		min_f = policy->cpuinfo.min_freq;
+		max_f = policy->cpuinfo.max_freq;
+		freq_next = min_f + load * (max_f - min_f) / 100;
 
 		/* No longer fully busy, reset rate_mult */
 		dbs_info->rate_mult = 1;
 
 		if (!od_tuners->powersave_bias) {
 			__cpufreq_driver_target(policy, freq_next,
-					CPUFREQ_RELATION_L);
+					CPUFREQ_RELATION_C);
 			return;
 		}
 
 		freq_next = od_ops.powersave_bias_target(policy, freq_next,
 					CPUFREQ_RELATION_L);
-		__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L);
+		__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
 	}
 }