Skip to content

Commit

Permalink
cpuidle: menu: Lookup CPU runqueues less
Browse files Browse the repository at this point in the history
The menu governer makes separate lookups of the CPU runqueue to get
load and number of IO waiters but it can be done with a single lookup.

Signed-off-by: Mel Gorman <mgorman@suse.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Mel Gorman authored and Rafael J. Wysocki committed Aug 6, 2014
1 parent 64b4ca5 commit 372ba8c
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 19 deletions.
17 changes: 7 additions & 10 deletions drivers/cpuidle/governors/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,9 @@ struct menu_device {
#define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)

static int get_loadavg(void)
static inline int get_loadavg(unsigned long load)
{
unsigned long this = this_cpu_load();


return LOAD_INT(this) * 10 + LOAD_FRAC(this) / 10;
return LOAD_INT(load) * 10 + LOAD_FRAC(load) / 10;
}

static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters)
Expand Down Expand Up @@ -175,13 +172,13 @@ static inline int which_bucket(unsigned int duration, unsigned long nr_iowaiters
* to be, the higher this multiplier, and thus the higher
* the barrier to go to an expensive C state.
*/
static inline int performance_multiplier(unsigned long nr_iowaiters)
static inline int performance_multiplier(unsigned long nr_iowaiters, unsigned long load)
{
int mult = 1;

/* for higher loadavg, we are more reluctant */

mult += 2 * get_loadavg();
mult += 2 * get_loadavg(load);

/* for IO wait tasks (per cpu!) we add 5x each */
mult += 10 * nr_iowaiters;
Expand Down Expand Up @@ -296,7 +293,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY);
int i;
unsigned int interactivity_req;
unsigned long nr_iowaiters;
unsigned long nr_iowaiters, cpu_load;

if (data->needs_update) {
menu_update(drv, dev);
Expand All @@ -312,7 +309,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
/* determine the expected residency time, round up */
data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length());

nr_iowaiters = nr_iowait_cpu(smp_processor_id());
get_iowait_load(&nr_iowaiters, &cpu_load);
data->bucket = which_bucket(data->next_timer_us, nr_iowaiters);

/*
Expand All @@ -331,7 +328,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
* duration / latency ratio. Adjust the latency limit if
* necessary.
*/
interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters);
interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load);
if (latency_req > interactivity_req)
latency_req = interactivity_req;

Expand Down
3 changes: 1 addition & 2 deletions include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ extern int nr_processes(void);
extern unsigned long nr_running(void);
extern unsigned long nr_iowait(void);
extern unsigned long nr_iowait_cpu(int cpu);
extern unsigned long this_cpu_load(void);

extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load);

extern void calc_global_load(unsigned long ticks);
extern void update_cpu_load_nohz(void);
Expand Down
7 changes: 7 additions & 0 deletions kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2385,6 +2385,13 @@ unsigned long nr_iowait_cpu(int cpu)
return atomic_read(&this->nr_iowait);
}

void get_iowait_load(unsigned long *nr_waiters, unsigned long *load)
{
struct rq *this = this_rq();
*nr_waiters = atomic_read(&this->nr_iowait);
*load = this->cpu_load[0];
}

#ifdef CONFIG_SMP

/*
Expand Down
7 changes: 0 additions & 7 deletions kernel/sched/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@

#include "sched.h"

unsigned long this_cpu_load(void)
{
struct rq *this = this_rq();
return this->cpu_load[0];
}


/*
* Global load-average calculations
*
Expand Down

0 comments on commit 372ba8c

Please sign in to comment.