# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxxxx
# Node ID 53f552ad404234c457fdd62560c9e8b0ea976674
# Parent 129ce4f59b6dc8e2406a13a058ef393894ff355f
[XEN] Various softirq cleanups. Main one is to always
call smp_processor_id() after any softirq, as rescheduling
may cause us to move to another processor on ia64
(spotted by Isaku Yamahata). Also get rid of many direct
callers of do_softirq() by creating new function
process_pending_timers().
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/domain.c | 7 +------
xen/arch/x86/smpboot.c | 3 +--
xen/common/page_alloc.c | 4 +---
xen/common/softirq.c | 16 +++++++++++-----
xen/common/timer.c | 9 +++++++++
xen/drivers/char/console.c | 3 +--
xen/include/xen/timer.h | 6 ++++++
7 files changed, 30 insertions(+), 18 deletions(-)
diff -r 129ce4f59b6d -r 53f552ad4042 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/arch/x86/domain.c Fri Jun 30 13:25:43 2006 +0100
@@ -67,16 +67,11 @@ static void default_idle(void)
void idle_loop(void)
{
- int cpu = smp_processor_id();
-
for ( ; ; )
{
page_scrub_schedule_work();
-
default_idle();
-
- if ( softirq_pending(cpu) )
- do_softirq();
+ do_softirq();
}
}
diff -r 129ce4f59b6d -r 53f552ad4042 xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/arch/x86/smpboot.c Fri Jun 30 13:25:43 2006 +0100
@@ -1197,8 +1197,7 @@ int __devinit __cpu_up(unsigned int cpu)
cpu_set(cpu, smp_commenced_mask);
while (!cpu_isset(cpu, cpu_online_map)) {
mb();
- if (softirq_pending(0))
- do_softirq();
+ process_pending_timers();
}
return 0;
}
diff -r 129ce4f59b6d -r 53f552ad4042 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/common/page_alloc.c Fri Jun 30 13:25:43 2006 +0100
@@ -388,7 +388,6 @@ void scrub_heap_pages(void)
{
void *p;
unsigned long pfn;
- int cpu = smp_processor_id();
printk("Scrubbing Free RAM: ");
@@ -398,8 +397,7 @@ void scrub_heap_pages(void)
if ( (pfn % ((100*1024*1024)/PAGE_SIZE)) == 0 )
printk(".");
- if ( unlikely(softirq_pending(cpu)) )
- do_softirq();
+ process_pending_timers();
/* Quick lock-free check. */
if ( allocated_in_map(pfn) )
diff -r 129ce4f59b6d -r 53f552ad4042 xen/common/softirq.c
--- a/xen/common/softirq.c Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/common/softirq.c Fri Jun 30 13:25:43 2006 +0100
@@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[
asmlinkage void do_softirq(void)
{
- unsigned int i, cpu = smp_processor_id();
+ unsigned int i, cpu;
unsigned long pending;
- pending = softirq_pending(cpu);
- ASSERT(pending != 0);
+ for ( ; ; )
+ {
+ /*
+ * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
+ * us to another processor.
+ */
+ cpu = smp_processor_id();
+ if ( (pending = softirq_pending(cpu)) == 0 )
+ break;
- do {
i = find_first_set_bit(pending);
clear_bit(i, &softirq_pending(cpu));
(*softirq_handlers[i])();
- } while ( (pending = softirq_pending(cpu)) != 0 );
+ }
}
void open_softirq(int nr, softirq_handler handler)
diff -r 129ce4f59b6d -r 53f552ad4042 xen/common/timer.c
--- a/xen/common/timer.c Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/common/timer.c Fri Jun 30 13:25:43 2006 +0100
@@ -327,6 +327,15 @@ static void timer_softirq_action(void)
}
+void process_pending_timers(void)
+{
+ unsigned int cpu = smp_processor_id();
+ ASSERT(!in_irq() && local_irq_is_enabled());
+ if ( test_and_clear_bit(TIMER_SOFTIRQ, &softirq_pending(cpu)) )
+ timer_softirq_action();
+}
+
+
static void dump_timerq(unsigned char key)
{
struct timer *t;
diff -r 129ce4f59b6d -r 53f552ad4042 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/drivers/char/console.c Fri Jun 30 13:25:43 2006 +0100
@@ -528,8 +528,7 @@ void console_endboot(void)
printk("%d... ", 3-i);
for ( j = 0; j < 100; j++ )
{
- if ( softirq_pending(smp_processor_id()) )
- do_softirq();
+ process_pending_timers();
mdelay(10);
}
}
diff -r 129ce4f59b6d -r 53f552ad4042 xen/include/xen/timer.h
--- a/xen/include/xen/timer.h Fri Jun 30 10:35:54 2006 +0100
+++ b/xen/include/xen/timer.h Fri Jun 30 13:25:43 2006 +0100
@@ -89,6 +89,12 @@ extern void kill_timer(struct timer *tim
extern void kill_timer(struct timer *timer);
/*
+ * Process pending timers on this CPU. This should be called periodically
+ * when performing work that prevents softirqs from running in a timely manner.
+ */
+extern void process_pending_timers(void);
+
+/*
* Bootstrap initialisation. Must be called before any other timer function.
*/
extern void timer_init(void);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|