diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/apm.c | 20 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/powernow-k7.c | 12 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/powernow-k8.c | 19 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | 3 | ||||
-rw-r--r-- | arch/i386/kernel/process.c | 68 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/i386/kernel/smpboot.c | 1 |
8 files changed, 59 insertions, 69 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 86e80c5..003548b 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -769,8 +769,26 @@ static int set_system_power_state(u_short state) static int apm_do_idle(void) { u32 eax; + u8 ret = 0; + int idled = 0; + int polling; + + polling = test_thread_flag(TIF_POLLING_NRFLAG); + if (polling) { + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + } + if (!need_resched()) { + idled = 1; + ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax); + } + if (polling) + set_thread_flag(TIF_POLLING_NRFLAG); + + if (!idled) + return 0; - if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) { + if (ret) { static unsigned long t; /* This always fails on some SMP boards running UP kernels. diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index caa9f77..871366b 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -377,10 +377,9 @@ acpi_cpufreq_cpu_init ( arg0.buffer.length = 12; arg0.buffer.pointer = (u8 *) arg0_buf; - data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); + data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); if (!data) return (-ENOMEM); - memset(data, 0, sizeof(struct cpufreq_acpi_io)); acpi_io_data[cpu] = data; diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 73a5dc5..edcd626 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c @@ -171,10 +171,9 @@ static int get_ranges (unsigned char *pst) unsigned int speed; u8 fid, vid; - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); + powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); if (!powernow_table) return -ENOMEM; - memset(powernow_table, 0, (sizeof(struct cpufreq_frequency_table) * (number_scales + 1))); for (j=0 ; j < number_scales; j++) { fid = *pst++; @@ -305,16 +304,13 @@ static int powernow_acpi_init(void) goto err0; } - acpi_processor_perf = kmalloc(sizeof(struct acpi_processor_performance), + acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance), GFP_KERNEL); - if (!acpi_processor_perf) { retval = -ENOMEM; goto err0; } - memset(acpi_processor_perf, 0, sizeof(struct acpi_processor_performance)); - if (acpi_processor_register_performance(acpi_processor_perf, 0)) { retval = -EIO; goto err1; @@ -337,14 +333,12 @@ static int powernow_acpi_init(void) goto err2; } - powernow_table = kmalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL); + powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL); if (!powernow_table) { retval = -ENOMEM; goto err2; } - memset(powernow_table, 0, ((number_scales + 1) * sizeof(struct cpufreq_frequency_table))); - pc.val = (unsigned long) acpi_processor_perf->states[0].control; for (i = 0; i < number_scales; i++) { u8 fid, vid; diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 2d5c9ad..68a1fc8 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -462,7 +462,6 @@ static int check_supported_cpu(unsigned int cpu) oldmask = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(cpu)); - schedule(); if (smp_processor_id() != cpu) { printk(KERN_ERR "limiting to cpu %u failed\n", cpu); @@ -497,9 +496,7 @@ static int check_supported_cpu(unsigned int cpu) out: set_cpus_allowed(current, oldmask); - schedule(); return rc; - } static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) @@ -913,7 +910,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi /* only run on specific CPU from here on */ oldmask = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); - schedule(); if (smp_processor_id() != pol->cpu) { printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); @@ -968,8 +964,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi err_out: set_cpus_allowed(current, oldmask); - schedule(); - return ret; } @@ -991,12 +985,11 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) if (!check_supported_cpu(pol->cpu)) return -ENODEV; - data = kmalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); + data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); if (!data) { printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); return -ENOMEM; } - memset(data,0,sizeof(struct powernow_k8_data)); data->cpu = pol->cpu; @@ -1026,7 +1019,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) /* only run on specific CPU from here on */ oldmask = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); - schedule(); if (smp_processor_id() != pol->cpu) { printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); @@ -1045,7 +1037,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) /* run on any CPU again */ set_cpus_allowed(current, oldmask); - schedule(); pol->governor = CPUFREQ_DEFAULT_GOVERNOR; pol->cpus = cpu_core_map[pol->cpu]; @@ -1080,7 +1071,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) err_out: set_cpus_allowed(current, oldmask); - schedule(); powernow_k8_cpu_exit_acpi(data); kfree(data); @@ -1116,17 +1106,14 @@ static unsigned int powernowk8_get (unsigned int cpu) set_cpus_allowed(current, oldmask); return 0; } - preempt_disable(); - + if (query_current_values_with_pending_wait(data)) goto out; khz = find_khz_freq_from_fid(data->currfid); - out: - preempt_enable_no_resched(); +out: set_cpus_allowed(current, oldmask); - return khz; } diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 0ea010a..edb9873 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -423,12 +423,11 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) } } - centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL); + centrino_model[cpu] = kzalloc(sizeof(struct cpu_model), GFP_KERNEL); if (!centrino_model[cpu]) { result = -ENOMEM; goto err_unreg; } - memset(centrino_model[cpu], 0, sizeof(struct cpu_model)); centrino_model[cpu]->model_name=NULL; centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000; diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 7a14fdf..1cb261f 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -99,14 +99,22 @@ EXPORT_SYMBOL(enable_hlt); */ void default_idle(void) { + local_irq_enable(); + if (!hlt_counter && boot_cpu_data.hlt_works_ok) { - local_irq_disable(); - if (!need_resched()) - safe_halt(); - else - local_irq_enable(); + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + while (!need_resched()) { + local_irq_disable(); + if (!need_resched()) + safe_halt(); + else + local_irq_enable(); + } + set_thread_flag(TIF_POLLING_NRFLAG); } else { - cpu_relax(); + while (!need_resched()) + cpu_relax(); } } #ifdef CONFIG_APM_MODULE @@ -120,29 +128,14 @@ EXPORT_SYMBOL(default_idle); */ static void poll_idle (void) { - int oldval; - local_irq_enable(); - /* - * Deal with another CPU just having chosen a thread to - * run here: - */ - oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); - - if (!oldval) { - set_thread_flag(TIF_POLLING_NRFLAG); - asm volatile( - "2:" - "testl %0, %1;" - "rep; nop;" - "je 2b;" - : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); - - clear_thread_flag(TIF_POLLING_NRFLAG); - } else { - set_need_resched(); - } + asm volatile( + "2:" + "testl %0, %1;" + "rep; nop;" + "je 2b;" + : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); } #ifdef CONFIG_HOTPLUG_CPU @@ -179,7 +172,9 @@ static inline void play_dead(void) */ void cpu_idle(void) { - int cpu = raw_smp_processor_id(); + int cpu = smp_processor_id(); + + set_thread_flag(TIF_POLLING_NRFLAG); /* endless idle loop with no priority at all */ while (1) { @@ -201,7 +196,9 @@ void cpu_idle(void) __get_cpu_var(irq_stat).idle_timestamp = jiffies; idle(); } + preempt_enable_no_resched(); schedule(); + preempt_disable(); } } @@ -244,15 +241,12 @@ static void mwait_idle(void) { local_irq_enable(); - if (!need_resched()) { - set_thread_flag(TIF_POLLING_NRFLAG); - do { - __monitor((void *)¤t_thread_info()->flags, 0, 0); - if (need_resched()) - break; - __mwait(0, 0); - } while (!need_resched()); - clear_thread_flag(TIF_POLLING_NRFLAG); + while (!need_resched()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (need_resched()) + break; + __mwait(0, 0); } } diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index b48ac63..fdfcb0c 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -129,9 +129,7 @@ struct drive_info_struct { char dummy[32]; } drive_info; EXPORT_SYMBOL(drive_info); #endif struct screen_info screen_info; -#ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); -#endif struct apm_info apm_info; EXPORT_SYMBOL(apm_info); struct sys_desc_table_struct { diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 47ec767..bc5a9d9 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -485,6 +485,7 @@ static void __devinit start_secondary(void *unused) * things done here to the most necessary things. */ cpu_init(); + preempt_disable(); smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); |