Skip to content

Commit

Permalink
cpuidle: menu governor: reduce latency on exit
Browse files Browse the repository at this point in the history
Move the state residency accounting and statistics computation off the hot
exit path.

On exit, the need to recompute statistics is recorded, and new statistics
will be computed when menu_select is called again.

The expected effect is to reduce processor wakeup latency from sleep
(C-states).  We are speaking of few hundreds of cycles reduction out of a
several microseconds latency (determined by the hardware transition), so
it is difficult to measure.

Signed-off-by: Corrado Zoccolo <[email protected]>
Cc: Venkatesh Pallipadi <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Adam Belay <[email protected]
Acked-by: Arjan van de Ven <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
czoccolo authored and torvalds committed Sep 22, 2009
1 parent 69d2587 commit 672917d
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion drivers/cpuidle/governors/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@

struct menu_device {
int last_state_idx;
int needs_update;

unsigned int expected_us;
u64 predicted_us;
Expand Down Expand Up @@ -166,6 +167,8 @@ static inline int performance_multiplier(void)

static DEFINE_PER_CPU(struct menu_device, menu_devices);

static void menu_update(struct cpuidle_device *dev);

/**
* menu_select - selects the next idle state to enter
* @dev: the CPU
Expand All @@ -180,6 +183,11 @@ static int menu_select(struct cpuidle_device *dev)
data->last_state_idx = 0;
data->exit_us = 0;

if (data->needs_update) {
menu_update(dev);
data->needs_update = 0;
}

/* Special case when user has set very strict latency requirement */
if (unlikely(latency_req == 0))
return 0;
Expand Down Expand Up @@ -231,13 +239,23 @@ static int menu_select(struct cpuidle_device *dev)
}

/**
* menu_reflect - attempts to guess what happened after entry
* menu_reflect - records that data structures need update
* @dev: the CPU
*
* NOTE: it's important to be fast here because this operation will add to
* the overall exit latency.
*/
static void menu_reflect(struct cpuidle_device *dev)
{
struct menu_device *data = &__get_cpu_var(menu_devices);
data->needs_update = 1;
}

/**
* menu_update - attempts to guess what happened after entry
* @dev: the CPU
*/
static void menu_update(struct cpuidle_device *dev)
{
struct menu_device *data = &__get_cpu_var(menu_devices);
int last_idx = data->last_state_idx;
Expand Down

0 comments on commit 672917d

Please sign in to comment.