Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 88235
b: refs/heads/master
c: 783e391
h: refs/heads/master
i:
  88233: 2ca31aa
  88231: fe8d042
v: v3
  • Loading branch information
Venki Pallipadi authored and Linus Torvalds committed Apr 10, 2008
1 parent e8f61a7 commit 0d2e22a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 73 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a1e58bbdc969c3fe60addca7f2729779d22a83c1
refs/heads/master: 783e391b7b5b273cd20856d8f6f4878da8ec31b3
47 changes: 11 additions & 36 deletions trunk/arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
*/
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);

void disable_hlt(void)
{
Expand Down Expand Up @@ -190,9 +189,6 @@ void cpu_idle(void)
while (!need_resched()) {
void (*idle)(void);

if (__get_cpu_var(cpu_idle_state))
__get_cpu_var(cpu_idle_state) = 0;

check_pgt_cache();
rmb();
idle = pm_idle;
Expand Down Expand Up @@ -220,40 +216,19 @@ static void do_nothing(void *unused)
{
}

/*
* cpu_idle_wait - Used to ensure that all the CPUs discard old value of
* pm_idle and update to new pm_idle value. Required while changing pm_idle
* handler on SMP systems.
*
* Caller must have changed pm_idle to the new value before the call. Old
* pm_idle value will not be used by any CPU after the return of this function.
*/
void cpu_idle_wait(void)
{
unsigned int cpu, this_cpu = get_cpu();
cpumask_t map, tmp = current->cpus_allowed;

set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
put_cpu();

cpus_clear(map);
for_each_online_cpu(cpu) {
per_cpu(cpu_idle_state, cpu) = 1;
cpu_set(cpu, map);
}

__get_cpu_var(cpu_idle_state) = 0;

wmb();
do {
ssleep(1);
for_each_online_cpu(cpu) {
if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
cpu_clear(cpu, map);
}
cpus_and(map, map, cpu_online_map);
/*
* We waited 1 sec, if a CPU still did not call idle
* it may be because it is in idle and not waking up
* because it has nothing to do.
* Give all the remaining CPUS a kick.
*/
smp_call_function_mask(map, do_nothing, NULL, 0);
} while (!cpus_empty(map));

set_cpus_allowed(current, tmp);
smp_mb();
/* kick all the CPUs so that they exit out of pm_idle */
smp_call_function(do_nothing, NULL, 0, 1);
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);

Expand Down
47 changes: 11 additions & 36 deletions trunk/arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ EXPORT_SYMBOL(boot_option_idle_override);
*/
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);

static ATOMIC_NOTIFIER_HEAD(idle_notifier);

Expand Down Expand Up @@ -173,9 +172,6 @@ void cpu_idle(void)
while (!need_resched()) {
void (*idle)(void);

if (__get_cpu_var(cpu_idle_state))
__get_cpu_var(cpu_idle_state) = 0;

rmb();
idle = pm_idle;
if (!idle)
Expand Down Expand Up @@ -207,40 +203,19 @@ static void do_nothing(void *unused)
{
}

/*
* cpu_idle_wait - Used to ensure that all the CPUs discard old value of
* pm_idle and update to new pm_idle value. Required while changing pm_idle
* handler on SMP systems.
*
* Caller must have changed pm_idle to the new value before the call. Old
* pm_idle value will not be used by any CPU after the return of this function.
*/
void cpu_idle_wait(void)
{
unsigned int cpu, this_cpu = get_cpu();
cpumask_t map, tmp = current->cpus_allowed;

set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
put_cpu();

cpus_clear(map);
for_each_online_cpu(cpu) {
per_cpu(cpu_idle_state, cpu) = 1;
cpu_set(cpu, map);
}

__get_cpu_var(cpu_idle_state) = 0;

wmb();
do {
ssleep(1);
for_each_online_cpu(cpu) {
if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
cpu_clear(cpu, map);
}
cpus_and(map, map, cpu_online_map);
/*
* We waited 1 sec, if a CPU still did not call idle
* it may be because it is in idle and not waking up
* because it has nothing to do.
* Give all the remaining CPUS a kick.
*/
smp_call_function_mask(map, do_nothing, 0, 0);
} while (!cpus_empty(map));

set_cpus_allowed(current, tmp);
smp_mb();
/* kick all the CPUs so that they exit out of pm_idle */
smp_call_function(do_nothing, NULL, 0, 1);
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);

Expand Down

0 comments on commit 0d2e22a

Please sign in to comment.