CPUFreq addon in HAL

Holger Macht hmacht at suse.de
Tue Jul 11 06:29:13 PDT 2006


On Mon 10. Jul - 21:13:18, David Zeuthen wrote:
> 
> Hi,
> 
> Sorry for the lag, been traveling, busy with work and a bit sick.
> 
> On Wed, 2006-07-05 at 16:49 +0200, Holger Macht wrote:
> > Hi,
> > 
> > CPU frequency scaling is the last remaining important power management
> > technology that should be controllable from the desktop IMO, but that's
> > not possible yet. Or there's at least no common interface/ software
> > everybody agrees on.
> > 
> > Richard already proposed something similar in the past. His idea was to
> > control the different frequencies a CPU supports from higher level
> > applications on the desktop. His proposal was rejected, though.
> > 
> > So I'm doing a second apprach and I've got a different way of solving the
> > problem. It's implemented as a HAL addon which summarizes all cpufreq
> > capable CPUs into six DBus methods on the
> > org.freedesktop.Hal.Device.SystemPowerManagement interface.
> 
> I think this makes lots of sense.
> 
> > Addon-cpufreq supports kernel governors and also implements a userspace
> > controlling mechanism. That makes it the "all you need for CPUFreq"
> > application. Furthermore, to not make things unnecessarily complicated for
> > desktop applications, it is supposed to abstract all the different
> > settings you can make for the different governors. One thing which isn't
> > available yet, is the possibility to control the performance of
> > dynamically scaled CPUs. 
> 
> Yea, probably we want a D-BUS interface on each device object
> representing an actual CPU which exports

I thought about this possibility, too, but came to the conclusion that it
doesn't make sense. There main reasons are:

  1. There are several dependencies between the different CPUs. The
     cpufreq interfaces below /sys/devices/system/cpu/ lists all available
     CPUs, each in one directory. However, you cannot assume that you can
     simply control each CPU through it's single interface. Theres a file
     affected_cpus in each directory listing the CPUs which are controlled
     through this interface. So maybe it could look like:

	cpu0/cpufreq/
		--> controls cpu0, cpu1
	cpu1/cpufreq/
		--> controls cpu0, cpu1
		...

     or:
	cpu0/cpufreq/
		--> controls cpu0, cpu1, cpu2, cpu3
		...
     
     or:
	cpu0/cpufreq/
		--> only controls cpu0
	cpu1/cpufreq/
		--> only controls cpu1
		...
		
     I really don't want to export these dependencies. This would make
     things unnecessarily compicated for higher level applications.

  2. I can't imagine a use case were one might want to have different
     settings for different CPUs.
     
  3. Some of the cpufreq kernel developers even are agains the possibility to
     set different governors for the CPUs.

  4. There's a new powernow-k8 driver pending where you only can scale all
     CPUs at a time which would perfectly fit into the current desing.

  5. There's currently no such device object where to export it. There's
     only acpi_CPU*. Except in very new implementations, in general,
     cpufreq has nothing to do with acpi, it also works with apm or even
     without acpi _and_ apm.

> 
>  void SetIgnoreGovernor(bool ignoreGovernor)
>  bool GetIgnoreGovernor()

I don't know what these interfaces should actually do.

>  void SetCPUFrequency(int FreqInMHz)
> 
> or something? Maybe use hal properties for cpu frequency too? Or maybe
> not.

There's absolutely no need for setting a specific frequency for a CPU. You
just need fixed low, fixed high and a tuneable dynamic frequency scaling
mechanism.

> 
> > There's a method to set the performance (from 1
> > to 100) which can be easily used from other applications with showing a
> > nice progress bar or the like. That makes it unique in contrast to former
> > solutions.
> 
> So the abstraction is a slider "how much performance do you want"? I'm
> assuming this is dependent on the governor you choose.

No. It's actually the cleverness of addon-cpufreq that it's not depending
on the current governor. It maps the requested performance value to the
correct settings on each governor. If a specific value is set for one
governor, you should get the same performance as if it is set on another
governor. And if there should be noticeable differences, it's actually ore
a bug and no design problem.

> 
> Perhaps you could elaborate what the difference is between setting the
> slider to 1 versus 25 versus 50 versus 75 versus 100 for different
> governors? What's the user experience when changing it?

Also have a look at my other mail in this thread were I already explained
related parts to Kevin.

In general it sais, the higher the value the more often and the faster the
frequency is switched up. Each governor has some sort of fixed CPU load
limit (up_threshold) at which load to switch up frequencies. For instance,
the ondemand governor has the up_threshold set to 80 by default. This
corresponds to a SetPerformance value of 50. As an example, if you change
the performance to 75, the up_threshold is set to about 45. So if the CPU
load reaches a value higher than 45, the frequency is switched up. If the
up_threshold would be 80 and a process would only need 60 percent of CPU,
the frequency wouldn't be switched up. If the performance value would be 1
(lowest performance), the up_threshold would be 99. That means that the
frequency is really only increased if you have a process which needs all
CPU power (100%, for instance at compilation time).

> 
> (I could read the code I guess... but...)
> 
> Some people claim that _the_ litmus test when introducing a setting in
> the UI is that if the users can't figure out how the system will react
> when changing the setting... it probably shouldn't be there.. 

I think it's absolutely transparent to the user what this setting
does. The higher the value the faster the system performs, but the more
battery power is needed. For instance, you can have a progress bar like:

====================================================
| CPU performance (System performance)             |
|                                                  |
|    -min-----low-----med-----high-----max-        |
|                                                  |
====================================================

> 
> I'm not saying we shouldn't have such a setting (in fact I believe we
> probably should, hence my long reply below) in any UI.. I'm just curious
> what the semantics of this 1-100 variable integer is.

I hope you now understand what it does. And I think the other mail
explains that the GUI can map this 1 to 100 range to whatever it likes.

> 
> > The biggest advantage is that you get CPUFreq out of the box on every
> > system supporting HAL without the need to install another daemon. Another
> > one is that desktop applications like gnome-power-manager or kpowersave
> > can use one common interface after all.
> 
> So how does this interact in the event there is an existing daemon on
> the system such as e.g. cpuspeed or powernowd? That will be the case on
> many systems when they upgrade to a HAL version that includes this? I'm
> just curious about possible interferences and/or resonance and whether
> we should advise packagers to say e.g.
> 
>  Conflicts: cpuspeed
>  Conflicts: powernowd
> 
> when updating their HAL spec file.
> 
> (my hope here is that they can coexist at least until someone pokes your
> methods in the addon)

Yes, the addon just sits there and does nothing until someone sets a
governor through the SetCPUFreqGovernor interface. So they can coexist,
but but my goal actually is that cpuspeed, powernowd, don't forget
powersaved ;-) (at least the CPUFreq part of it), shouldn't be needed
anymore.

> 
> > It claims the following DBus interfaces on the
> > /org/freedesktop/Hal/devices/computer device:
> > 
> > 
> > Set a specific CPU frequency governor
> > -------------------------------------
> >   Interface: org.freedesktop.Hal.Device.SystemPowerManagement
> >   Member   : "SetCPUFreqGovernor"
> >   Type     : Method call with return
> > 
> >   Param:
> >     string : The governor to be set. This can be any arbitary string. Also
> > 	     governors which are not known can be set
> > 
> >   Return type:
> >     int    : 0 on success, 1 on error
> 
> Maybe throw an exception on error? Exceptions are more flexible since
> the user won't have to remember what the integer means and you can grow
> this as needed (it's somewhat like an enum in C). The only exception I
> can think of here is org.freedesktop.Hal.Device.SystemPowerManagement.
> UnknownGovernor.

Yes, I will look into this.

> Suggest also to return a boolean with TRUE only on success although we
> could get away with a void. 
> 
> Also you want to use PolicyKit here and introduce a privilege descriptor
> for whether the user is privileged (see tools/hal-storage-mount.c for
> details or just ask on the list and/or IRC). 
> 
> Specifically you want throw a org.freedesktop.Hal.Device.
> SystemPowerManagement.PermissionDenied exception with the name of the
> privilege as the first word in the detail. This way applications
> catching that error can deal with it and, optionally, use
> libpolkit-grant to get the privilege.

Yes, we definitely need a possibility to forbid the use of this interface
for the usual user or in general. But I have to look into PolicyKit in the
first instance.

Same applies to SetCPUFreqPerformance and SetCPUFreqConsider Nice.

[...]

> > Get the current active governor
> > -------------------------------
> >   Interface: org.freedesktop.Hal.Device.SystemPowerManagement
> >   Member   : "GetCPUFreqGovernor"
> >   Type     : Method call with return
> > 
> >   Return type:
> >     string : The current active governor
> 
> Perhaps this should be a hal property instead? Maybe not if it can
> change underneath us.

No, this can't change underneath. But again, I don't know which device
object to use for this. Would
org.freedesktop.Hal.Device.SystemPowerManagement be ok?

Same applies to GetCPUFreqPerformance and GetCPUFreqConsider Nice.

[...]

> How about a function to get a list of available governors?

Kevin already proposed it and I can add it. But if the other settings are
exported as hal property, wouldn't it make sense to do the same for the
available governors?


> > The addon basically consists of five parts:
> > 
> >   1. One interface which contains all methods which are common for all
> >      governors (see DBus interfaces above)
> > 
> >   2. Some helper functions
> > 
> >   3. The userspace governor implementation with the CPULoad calculation
> >      mechanism
> > 
> >   4. The ondemand governor implementation
> > 
> >   5. DBus/HAL integration
> > 
> > Current addons only consist of one source file. However, I don't think
> > that makes sense for addon-cpufreq. If this would be a independent
> > project, I would have separated these parts into more different files. But
> > for now, I've just put the userspace part into two files (header, source)
> > and the remaining parts into another two files (header, source). It would
> > of course be possible to only have one source file and thus get rid of the
> > header files if this is desired.
> > 
> > I've appended a somewhat patch to accomplish all this. Please comment...
> > 
> > If you guys don't agree that this could be added to HAL as an addon, maybe
> > the above mentioned interfaces can be implemented by installing some
> > scripts like hal-system-power-cpufreq-set-governor. Then I'm trying to get
> > org.freedesktop.CPUFreq for a separate daemon and can call the DBus
> > methods inside them. All other people can then of course do whatever they
> > like in those scripts.
> 
> Personally I think it makes sense to add. I'm unsure how this is handled
> on FreeBSD and Solaris? It looks to me as the interface is sufficiently
> abstract.

I hope so.

> 
> Also, if you can send a patch for the hal spec detailing all the methods
> and the exceptions they throw it would be great. For example, the
> PermissionDenied exception with the constraint that the first word of
> the detail of the exception is the name of the privilege needed is as a
> matter of fact part of the ABI. [1]

Of course I can do that as soon as we have agreed on the remaining open
issues and I have adjusted the code.

> 
> [1] : Unfortunately I've failed at convincing the other D-BUS developers
> that the D-BUS introspection data format should be amended to list what
> exceptions the code may throw.
> 
> Comments on the patch
> 
> 
> > +int get_cpu_count(void)
> 
> Maybe use sysconf(3) here?

sysconf doesn't provide this information.

> 
> > +static void dbus_add_method(LibHalContext *halctx, const char *method,
> > +				const char *signature)
> > +{
> > +	libhal_device_property_strlist_append(halctx,
> > +		      "/org/freedesktop/Hal/devices/computer",
> > +		      "org.freedesktop.Hal.Device.SystemPowerManagement.method_names",
> > +		      method,
> > +		      NULL);
> > +	libhal_device_property_strlist_append(halctx,
> > +		      "/org/freedesktop/Hal/devices/computer",
> > +		      "org.freedesktop.Hal.Device.SystemPowerManagement.method_signatures",
> > +		      signature,
> > +		      NULL);
> > +}
> 
> is used by
> 
> > +		dbus_add_method(halctx, "SetCPUFreqGovernor", "s");
> > +		dbus_add_method(halctx, "SetCPUFreqPerformance", "i");
> > +		dbus_add_method(halctx, "SetCPUFreqConsiderNice", "b");
> > +		dbus_add_method(halctx, "GetCPUFreqGovernor", "");
> > +		dbus_add_method(halctx, "GetCPUFreqPerformance", "");
> > +		dbus_add_method(halctx, "GetCPUFreqConsiderNice", "");
> 
> This shouldn't be necessary.

But it is. As soon as I remove these calls, I don't see the methods in
lshal output and they also can't be used. But maybe I'm using
libhal_claim_interface in a wrong...

> 
> 
> > +	dbus_bus_add_match(dbus_connection,
> > +			   "type='method_call',"
> > +			   "interface='" DBUS_INTERFACE "',", NULL);
> 
> Pretty sure this isn't needed either.

Yes, this isn't needed.


Regards,
	Holger


More information about the hal mailing list