Skip to content

Commit

Permalink
cpuidle/idle: Move the cpuidle_idle_call function to idle.c
Browse files Browse the repository at this point in the history
The cpuidle_idle_call does nothing more than calling the three individuals
function and is no longer used by any arch specific code but only in the
cpuidle framework code.

We can move this function into the idle task code to ensure better
proximity to the scheduler code.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: rjw@rjwysocki.net
Cc: preeti@linux.vnet.ibm.com
Link: http://lkml.kernel.org/r/1393832934-11625-2-git-send-email-daniel.lezcano@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Daniel Lezcano authored and Ingo Molnar committed Mar 11, 2014
1 parent 907e30f commit 30cdd69
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 51 deletions.
49 changes: 0 additions & 49 deletions drivers/cpuidle/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,55 +172,6 @@ void cpuidle_reflect(struct cpuidle_device *dev, int index)
cpuidle_curr_governor->reflect(dev, index);
}

/**
* cpuidle_idle_call - the main idle loop
*
* NOTE: no locks or semaphores should be used here
* return non-zero on failure
*/
int cpuidle_idle_call(void)
{
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int next_state, entered_state, ret;
bool broadcast;

ret = cpuidle_enabled(drv, dev);
if (ret < 0)
return ret;

/* ask the governor for the next state */
next_state = cpuidle_select(drv, dev);

if (need_resched()) {
dev->last_residency = 0;
/* give the governor an opportunity to reflect on the outcome */
cpuidle_reflect(dev, next_state);
local_irq_enable();
return 0;
}

broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP);

if (broadcast &&
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
return -EBUSY;

trace_cpu_idle_rcuidle(next_state, dev->cpu);

entered_state = cpuidle_enter(drv, dev, next_state);

trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);

if (broadcast)
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);

/* give the governor an opportunity to reflect on the outcome */
cpuidle_reflect(dev, entered_state);

return 0;
}

/**
* cpuidle_install_idle_handler - installs the cpuidle idle loop handler
*/
Expand Down
2 changes: 0 additions & 2 deletions include/linux/cpuidle.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ extern int cpuidle_enter(struct cpuidle_driver *drv,
struct cpuidle_device *dev, int index);
extern void cpuidle_reflect(struct cpuidle_device *dev, int index);

extern int cpuidle_idle_call(void);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
extern struct cpuidle_driver *cpuidle_get_driver(void);
extern struct cpuidle_driver *cpuidle_driver_ref(void);
Expand Down Expand Up @@ -160,7 +159,6 @@ static inline int cpuidle_enter(struct cpuidle_driver *drv,
struct cpuidle_device *dev, int index)
{return -ENODEV; }
static inline void cpuidle_reflect(struct cpuidle_device *dev, int index) { }
static inline int cpuidle_idle_call(void) { return -ENODEV; }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
Expand Down
56 changes: 56 additions & 0 deletions kernel/sched/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,62 @@ void __weak arch_cpu_idle(void)
local_irq_enable();
}

#ifdef CONFIG_CPU_IDLE
/**
* cpuidle_idle_call - the main idle function
*
* NOTE: no locks or semaphores should be used here
* return non-zero on failure
*/
static int cpuidle_idle_call(void)
{
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
int next_state, entered_state, ret;
bool broadcast;

ret = cpuidle_enabled(drv, dev);
if (ret < 0)
return ret;

/* ask the governor for the next state */
next_state = cpuidle_select(drv, dev);

if (need_resched()) {
dev->last_residency = 0;
/* give the governor an opportunity to reflect on the outcome */
cpuidle_reflect(dev, next_state);
local_irq_enable();
return 0;
}

broadcast = !!(drv->states[next_state].flags & CPUIDLE_FLAG_TIMER_STOP);

if (broadcast &&
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu))
return -EBUSY;

trace_cpu_idle_rcuidle(next_state, dev->cpu);

entered_state = cpuidle_enter(drv, dev, next_state);

trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);

if (broadcast)
clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);

/* give the governor an opportunity to reflect on the outcome */
cpuidle_reflect(dev, entered_state);

return 0;
}
#else
static inline int cpuidle_idle_call(void)
{
return -ENODEV;
}
#endif

/*
* Generic idle loop implementation
*/
Expand Down

0 comments on commit 30cdd69

Please sign in to comment.