Reworking pm_qos
The pm_qos code currently defines three quality of service parameters for which requirements may be specified: CPU latency (PM_QOS_CPU_DMA_LATENCY), network response latency (PM_QOS_NETWORK_LATENCY), and network throughput (PM_QOS_NETWORK_THROUGHPUT). The first two are specified in microseconds; throughput is specified in KB/sec. Currently, CPU latency requirements are observed by the cpuidle subsystem, and network latency is observed only by the mac80211 layer. Any requests for a minimum network throughput will fall on deaf ears in current kernels; given the effectiveness of asking your editor's ISP for better service, one assumes that the ignoring of throughput requests is simply a clever elimination of useless work by the networking hackers.
The API for specifying quality of service parameters is:
#include <linux/pm_qos_params.h> int pm_qos_add_requirement(int qos, char *name, s32 value); int pm_qos_update_requirement(int qos, char *name, s32 value); void pm_qos_remove_requirement(int qos, char *name);
For each of the above functions, qos is one of the parameters listed above, name identifies the subsystem specifying the requirement, and value is the new requirement. The name string is used to identify a specific request in pm_qos_update_requirement() and pm_qos_remove_requirement(); it must match the value given when the requirement was first added.
Kernel code which may make decisions affecting quality of service should pay attention to the current requirements. There are two ways of doing that, one of which being to just ask pm_qos what the tightest requirement in effect is:
int pm_qos_requirement(int qos);
The alternative is to register a notifier which is called whenever a given requirement changes, using:
int pm_qos_add_notifier(int qos, struct notifier_block *notifier); int pm_qos_remove_notifier(int qos, struct notifier_block *notifier);
This API has been around for some time, though it remains lightly used within the kernel. One complaint which has been made is that the use of strings to identify requirements leads to inefficient behavior: changing a requirement involves walking a list and doing a bunch of string comparisons. Requirements are, by their nature, specified by latency-sensitive code, so it makes sense that the process should be fast. The use of arbitrary strings also opens up a distant possibility of confusion should two developers accidentally choose the same name.
In response to these problems, pm_qos hacker Mark Gross has proposed some changes to the
API. With the new version, "requirements" would become "requests," and the
use of strings to identify them would be removed. The new API for the
specification of requirements requests is:
struct pm_qos_request_list *pm_qos_add_request(int qos, s32 value); void pm_qos_update_request(struct pm_qos_request_list *pm_qos_req, s32 new_value); void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req);
The pm_qos_request_list structure type is opaque to callers; it serves only as a handle to identify a specific request. Changes and removals can now be done with no list traversals and no string comparisons. On the other side, pm_qos_requirement() becomes pm_qos_request(), but the API is otherwise unchanged.
This change seems uncontroversial, and it should address the criticisms
which have been made against this API. Unless something surprising
happens, the new API will probably be merged for 2.6.35.
Index entries for this article | |
---|---|
Kernel | Power management |
Posted May 6, 2010 7:47 UTC (Thu)
by Gollum (guest, #25237)
[Link] (1 responses)
i.e. why am I staying awake so much? Oh, *name process is asking for 0 CPU latency.
Now it is:
Why am I staying awake so much? Oh, something (I don't know what) is asking for 0 CPU latency.
Or am I missing something?
Posted Jun 21, 2010 4:07 UTC (Mon)
by mgross (guest, #38112)
[Link]
We are working on adding something better these days, (hopefully for 2.6.36 though)
Reworking pm_qos
Reworking pm_qos