Re: softirq buggy [Re: Serial port latency]

From: Manfred Spraul (manfred@colorfullife.com)
Date: Sat Apr 07 2001 - 17:28:03 EST


Pavel Machek wrote:
>
> Ok. I was missing the fact it is checked on going userspace.
>

What about the attached patch?

--
	Manfred

// $Header$ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 4 // SUBLEVEL = 3 // EXTRAVERSION = -ac3 --- 2.4/include/linux/interrupt.h Thu Feb 22 22:29:53 2001 +++ build-2.4/include/linux/interrupt.h Sat Apr 7 23:51:31 2001 @@ -269,4 +269,25 @@ extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */ extern unsigned int probe_irq_mask(unsigned long); /* returns mask of ISA interrupts */ +/** + * cpu_is_idle - helper function for idle functions + * + * pm_idle functions must call this function to verify that + * the cpu is really idle. It must be called with disabled + * local interrupts. + * Return values: + * 0: cpu was not idle. + * 1: go into power saving mode. + */ +static inline int cpu_is_idle(void) +{ + if (current->need_resched) { + return 0; + } + if (softirq_active(smp_processor_id()) & softirq_mask(smp_processor_id())) { + do_softirq(); + return 0; + } + return 1; +} #endif --- 2.4/arch/i386/kernel/process.c Thu Feb 22 22:28:52 2001 +++ build-2.4/arch/i386/kernel/process.c Sat Apr 7 23:51:46 2001 @@ -73,6 +73,7 @@ hlt_counter--; } + /* * We use this if we don't have any better * idle routine.. @@ -81,7 +82,7 @@ { if (current_cpu_data.hlt_works_ok && !hlt_counter) { __cli(); - if (!current->need_resched) + if (cpu_is_idle()) safe_halt(); else __sti(); @@ -92,26 +93,21 @@ * On SMP it's slightly faster (but much more power-consuming!) * to poll the ->need_resched flag instead of waiting for the * cross-CPU IPI to arrive. Use this option with caution. + * + * Isn't this identical to default_idle with the 'no-hlt' boot + * option? <manfred@colorfullife.com> */ static void poll_idle (void) { int oldval; + for(;;) { + if (!cpu_is_idle()) + break; + __sti(); + rep_nop(); + } __sti(); - - /* - * Deal with another CPU just having chosen a thread to - * run here: - */ - oldval = xchg(&current->need_resched, -1); - - if (!oldval) - asm volatile( - "2:" - "cmpl $-1, %0;" - "rep; nop;" - "je 2b;" - : :"m" (current->need_resched)); } /* --- 2.4/drivers/acpi/cpu.c Sat Apr 7 22:02:01 2001 +++ build-2.4/drivers/acpi/cpu.c Sat Apr 7 23:55:17 2001 @@ -148,7 +148,7 @@ unsigned long diff; __cli(); - if (current->need_resched) + if (!cpu_is_idle()) goto out; if (acpi_bm_activity()) goto sleep2; @@ -171,7 +171,7 @@ unsigned long diff; __cli(); - if (current->need_resched) + if (!cpu_is_idle()) goto out; if (acpi_bm_activity()) goto sleep2; @@ -205,7 +205,7 @@ unsigned long diff; __cli(); - if (current->need_resched) + if (!cpu_is_idle()) goto out; time = acpi_read_pm_timer(); @@ -235,7 +235,7 @@ unsigned long diff; __cli(); - if (current->need_resched) + if (!cpu_is_idle()) goto out; time = acpi_read_pm_timer(); acpi_c1_count++;

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Apr 15 2001 - 21:00:10 EST