mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* Interrupt starvation points
@ 2005-02-11 17:05 Daniel Walker
  2005-02-11 17:30 ` Ingo Molnar
  2005-02-11 20:04 ` Russell King
  0 siblings, 2 replies; 5+ messages in thread
From: Daniel Walker @ 2005-02-11 17:05 UTC (permalink / raw)
  To: linux-kernel

        I found some points during schedule when interrupts are off for
long periods . These two patches seem to help. One enables interrupts
inside schedule() , so that interrupts are enabled after each
need-resched loop, then disabled again before __schedule() is called. 

        The other patch enabled interrupt before calling up on
kernel_sem ..This one could use some thinking over. I did this cause
up() is very expensive on ARM , and combined with the looping above
interrupts can stay off for a long time .. 


Daniel


Index: linux-2.6.10/kernel/sched.c
===================================================================
--- linux-2.6.10.orig/kernel/sched.c	2005-02-08 22:32:48.000000000 +0000
+++ linux-2.6.10/kernel/sched.c	2005-02-08 22:33:58.000000000 +0000
@@ -3038,9 +3038,10 @@
 		send_sig(SIGUSR2, current, 1);
 	}
 	do {
+		local_irq_disable();
 		__schedule();
+		local_irq_enable(); // TODO: do sti; ret
 	} while (unlikely(test_thread_flag(TIF_NEED_RESCHED)));
-	local_irq_enable(); // TODO: do sti; ret
 }
 
 EXPORT_SYMBOL(schedule);


Index: linux-2.6.10/lib/kernel_lock.c
===================================================================
--- linux-2.6.10.orig/lib/kernel_lock.c	2005-02-08 18:16:30.000000000 +0000
+++ linux-2.6.10/lib/kernel_lock.c	2005-02-08 22:53:09.000000000 +0000
@@ -114,7 +114,9 @@
 
 void __lockfunc __release_kernel_lock(void)
 {
+	local_irq_enable();
 	up(&kernel_sem);
+	local_irq_disable();
 }
 
 /*





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Interrupt starvation points
  2005-02-11 17:05 Interrupt starvation points Daniel Walker
@ 2005-02-11 17:30 ` Ingo Molnar
  2005-02-11 17:36   ` Daniel Walker
  2005-02-11 20:04 ` Russell King
  1 sibling, 1 reply; 5+ messages in thread
From: Ingo Molnar @ 2005-02-11 17:30 UTC (permalink / raw)
  To: Daniel Walker; +Cc: linux-kernel


* Daniel Walker <dwalker@mvista.com> wrote:

>         I found some points during schedule when interrupts are off
> for long periods . These two patches seem to help. One enables
> interrupts inside schedule() , so that interrupts are enabled after
> each need-resched loop, then disabled again before __schedule() is
> called. 
> 
>         The other patch enabled interrupt before calling up on
> kernel_sem ..This one could use some thinking over. I did this cause
> up() is very expensive on ARM , and combined with the looping above
> interrupts can stay off for a long time .. 

i'm wondering what the best approach would be. Right now if
DIRECT_PREEMPT is enabled [it's disabled currently] and a higher-prio
task has been woken up we switch to it without ever enabling interrupts
again. Re-enabling interrupts during schedule() will reduce irq
latencies but will lengthen critical sections.

	Ingo

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Interrupt starvation points
  2005-02-11 17:30 ` Ingo Molnar
@ 2005-02-11 17:36   ` Daniel Walker
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Walker @ 2005-02-11 17:36 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel

On Fri, 2005-02-11 at 09:30, Ingo Molnar wrote:
> 
> i'm wondering what the best approach would be. Right now if
> DIRECT_PREEMPT is enabled [it's disabled currently] and a higher-prio
> task has been woken up we switch to it without ever enabling interrupts
> again. Re-enabling interrupts during schedule() will reduce irq
> latencies but will lengthen critical sections.


	Yeah, it's a trade off .. The longest points that I observed involved
kernel threads like desched . Things that the scheduler() regularly
wakes up anyways. I would imagine there is an upper bound on the number
of tasks the scheduler can wake up.

Daniel


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Interrupt starvation points
  2005-02-11 17:05 Interrupt starvation points Daniel Walker
  2005-02-11 17:30 ` Ingo Molnar
@ 2005-02-11 20:04 ` Russell King
  2005-02-11 21:52   ` Daniel Walker
  1 sibling, 1 reply; 5+ messages in thread
From: Russell King @ 2005-02-11 20:04 UTC (permalink / raw)
  To: Daniel Walker; +Cc: linux-kernel

On Fri, Feb 11, 2005 at 09:05:21AM -0800, Daniel Walker wrote:
>         The other patch enabled interrupt before calling up on
> kernel_sem ..This one could use some thinking over. I did this cause
> up() is very expensive on ARM , and combined with the looping above
> interrupts can stay off for a long time .. 

Please substantiate your claim that up() is very expensive on ARM.
I disagree:

#define __up_op(ptr,wake)                       \
        ({                                      \
        __asm__ __volatile__(                   \
        "@ up_op\n"                             \
"       mrs     ip, cpsr\n"                     \
"       orr     lr, ip, #128\n"                 \
"       msr     cpsr_c, lr\n"                   \
"       ldr     lr, [%0]\n"                     \
"       adds    lr, lr, %1\n"                   \
"       str     lr, [%0]\n"                     \
"       msr     cpsr_c, ip\n"                   \
"       movle   ip, %0\n"                       \
"       blle    " #wake                         \
        :                                       \
        : "r" (ptr), "I" (1)                    \
        : "ip", "lr", "cc", "memory");          \
        })

static inline void up(struct semaphore * sem)
{
        __up_op(sem, __up_wakeup);
}

Looks like 9 instructions for the uncontended case to me.  If you're
worried about 9 instructions being expensive, please work on GCC to
improve its optimisation capabilities first.  There's room there for
improvement across the whole kernel than just the above 9 instructions.

Plus, after you've read the above code, wouldn't you think that adding
the "enable interrupts + disable interrupts" around an up() operation
(which itself immediately disables interrupts again) is just adding
extra instructions to the kernel, which corresponds directly to lower
performance?

-- 
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Interrupt starvation points
  2005-02-11 20:04 ` Russell King
@ 2005-02-11 21:52   ` Daniel Walker
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Walker @ 2005-02-11 21:52 UTC (permalink / raw)
  To: Russell King; +Cc: linux-kernel

On Fri, 2005-02-11 at 12:04, Russell King wrote:
> 
> Please substantiate your claim that up() is very expensive on ARM.
> I disagree:

	I should have made it clear that I was talking about the RT version of
up() . The RT version doesn't have any assembly in it, and it is
expensive. 

> Plus, after you've read the above code, wouldn't you think that adding
> the "enable interrupts + disable interrupts" around an up() operation
> (which itself immediately disables interrupts again) is just adding
> extra instructions to the kernel, which corresponds directly to lower
> performance?

	Not in the RT case. However, I never said that was a proper fix, I was
just producing code that helped in my tests.

Daniel


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-02-11 21:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-11 17:05 Interrupt starvation points Daniel Walker
2005-02-11 17:30 ` Ingo Molnar
2005-02-11 17:36   ` Daniel Walker
2005-02-11 20:04 ` Russell King
2005-02-11 21:52   ` Daniel Walker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®