On Saturday 14 February 2004 00:41, Ross Dickson wrote: > On Friday 13 February 2004 21:17, Prakash K. Cheemplavam wrote: > > Hi, > > > > I am just testing this patch with latest 2.6.3-rc2-mm1. It works in that > > sense, that my machine doesn't lock up of APIC issue. (If it locks up - > > hasn't done yet - then because of something else, I am currently > > discssing it in another thread...) > > > > But it doesn't work in the sense of cooling my machine down. Though > > athcool reports disconnect is activated it behaves like it is not, ie, > > turning disconnect off makes no difference in temperatures. Your old > > tack patch in conjunction with 2.6.2-rc1 (linus) works like a charm, ie > > no lock-ups and less temp. > > > > Thanks Prakash for testing it and spotting thermal problem. > > Here are some temperatures from my machine read from the bios on reboot. > I gave it minimal activity for the minutes prior to reboot. > > Win98, 47C > XPHome, 42C > Patched Linux 2.4.24 (1000Hz), 40C > Patched Linux 2.6.3-rc1-mm1, 53C OUCH! > > Sorry, I will have to go through my latest patch and see why the temp differs > so much between 2.4 and 2.6. I currently use patched 2.4.24 with Suse 8.2 for > convenience. When it stopped the lockups on 2.6 I thought the 2.6 was > working the same way. > Found the problem for 2.6 After fixing it the 2.6 temperature is Patched Linux 2.6.3-rc1-mm1, 38C Ambient today is 1C cooler also. The fix is to put the brackets back on "!need_resched()" so that we call the function and test its return value - not just test the function pointer! Should be as follows: static void c1halt_idle(void) { if (!hlt_counter && current_cpu_data.hlt_works_ok) { local_irq_disable(); /* only hlt disconnect if more than 1.6% of apic interval remains */ if( (!need_resched() ) && (apic_read(APIC_TMCCT) > (apic_read(APIC_TMICT)>>6))) { ndelay(500); /* helps nforce2 but adds 0.5us hard int latency */ safe_halt(); /* nothing better to do until we wake up */ } else local_irq_enable(); } } Again attached in tarball, 2.4 patch was not changed. Revision1 patch for 2.6.3-rc1-mm1: ---CUTHERE--- --- linux-2.6.3-rc1-mm1/arch/i386/kernel/process.c 2004-02-11 21:29:49.000000000 +1000 +++ linux-2.6.3-rc1-mm1-nf/arch/i386/kernel/process.c 2004-02-11 23:44:04.000000000 +1000 @@ -50,10 +50,11 @@ #include #include #ifdef CONFIG_MATH_EMULATION #include #endif +#include #include #include #include @@ -92,11 +93,11 @@ EXPORT_SYMBOL(enable_hlt); /* * We use this if we don't have any better * idle routine.. */ -void default_idle(void) +static void default_idle(void) { if (!hlt_counter && current_cpu_data.hlt_works_ok) { local_irq_disable(); if (!need_resched()) safe_halt(); @@ -104,10 +105,29 @@ void default_idle(void) local_irq_enable(); } } /* + * We use this to avoid nforce2 lockups + * Reduces frequency of C1 disconnects + */ +static void c1halt_idle(void) +{ + if (!hlt_counter && current_cpu_data.hlt_works_ok) { + local_irq_disable(); + /* only hlt disconnect if more than 1.6% of apic interval remains */ + if( (!need_resched()) && + (apic_read(APIC_TMCCT) > (apic_read(APIC_TMICT)>>6))) { + ndelay(500); /* helps nforce2 but adds 0.5us hard int latency */ + safe_halt(); /* nothing better to do until we wake up */ + } + else + local_irq_enable(); + } +} + +/* * On SMP it's slightly faster (but much more power-consuming!) * to poll the ->work.need_resched flag instead of waiting for the * cross-CPU IPI to arrive. Use this option with caution. */ static void poll_idle (void) @@ -195,20 +215,18 @@ static inline void check_cpu_quiescent(v * The idle thread. There's no useful work to be * done, so just try to conserve power and have a * low exit latency (ie sit in a loop waiting for * somebody to say that they'd like to reschedule) */ +static void (*idle)(void); void cpu_idle (void) { /* endless idle loop with no priority at all */ while (1) { while (!need_resched()) { - void (*idle)(void) = pm_idle; - if (!idle) - idle = default_idle; - + idle = pm_idle ? pm_idle : default_idle; check_cpu_quiescent(); irq_stat[smp_processor_id()].idle_timestamp = jiffies; idle(); } schedule(); @@ -260,16 +278,18 @@ void __init select_idle_routine(const st static int __init idle_setup (char *str) { if (!strncmp(str, "poll", 4)) { printk("using polling idle threads.\n"); - pm_idle = poll_idle; + idle = poll_idle; } else if (!strncmp(str, "halt", 4)) { printk("using halt in idle threads.\n"); - pm_idle = default_idle; + idle = default_idle; + } else if (!strncmp(str, "C1halt", 6)) { + printk("using C1 halt disconnect friendly idle threads.\n"); + idle = c1halt_idle; } - return 1; } __setup("idle=", idle_setup); ---CUTHERE---