Re: softirq buggy [Re: Serial port latency]

Manfred Spraul
2001-04-08T08:26:41Z

[-- Attachment #1: Type: text/plain, Size: 132 bytes --]

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

What about the attached patch?

--
Manfred

[-- Attachment #2: patch-cpu-idle --]
[-- Type: text/plain, Size: 2858 bytes --]

// $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++;