File 20714-process-pending-softirqs.patch of Package xen
# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1261506934 0
# Node ID a60f508548a848ab7f92a5960dcc5df8e75f8c0f
# Parent affb589507a7bea502ce7d0c8c3fa47ec9e4ff22
Replace process_pending_timers() with process_pending_softirqs().
This ensures that any critical softirqs are handled in a timely manner
(e.g., TIME_CALIBRATE_SOFTIRQ) while still avoiding being preempted by
the scheduler (by SCHEDULE_SOFTIRQ), which is the reason for avoiding
use of do_softirq() directly.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -878,7 +878,7 @@ int __init construct_dom0(
((unsigned int *)vphysmap_start)[pfn] = mfn;
set_gpfn_from_mfn(mfn, pfn);
if (!(pfn & 0xfffff))
- process_pending_timers();
+ process_pending_softirqs();
}
si->first_p2m_pfn = pfn;
si->nr_p2m_frames = d->tot_pages - count;
@@ -898,7 +898,7 @@ int __init construct_dom0(
++alloc_epfn;
#endif
if (!(pfn & 0xfffff))
- process_pending_timers();
+ process_pending_softirqs();
}
}
BUG_ON(pfn != d->tot_pages);
@@ -920,7 +920,7 @@ int __init construct_dom0(
#undef pfn
page++; pfn++;
if (!(pfn & 0xfffff))
- process_pending_timers();
+ process_pending_softirqs();
}
}
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -1295,7 +1295,7 @@ void __cpu_die(unsigned int cpu)
}
mdelay(100);
mb();
- process_pending_timers();
+ process_pending_softirqs();
}
printk(KERN_ERR "CPU %u didn't die...\n", cpu);
}
@@ -1455,7 +1455,7 @@ int __devinit __cpu_up(unsigned int cpu)
cpu_set(cpu, smp_commenced_mask);
while (!cpu_isset(cpu, cpu_online_map)) {
mb();
- process_pending_timers();
+ process_pending_softirqs();
}
return 0;
}
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -583,7 +583,7 @@ void __init scrub_heap_pages(void)
for ( mfn = first_valid_mfn; mfn < max_page; mfn++ )
{
- process_pending_timers();
+ process_pending_softirqs();
/* Quick lock-free check. */
if ( allocated_in_map(mfn) )
--- a/xen/common/softirq.c
+++ b/xen/common/softirq.c
@@ -22,7 +22,7 @@ irq_cpustat_t irq_stat[NR_CPUS];
static softirq_handler softirq_handlers[NR_SOFTIRQS];
-asmlinkage void do_softirq(void)
+static void __do_softirq(unsigned long ignore_mask)
{
unsigned int i, cpu;
unsigned long pending;
@@ -38,7 +38,7 @@ asmlinkage void do_softirq(void)
if ( rcu_pending(cpu) )
rcu_check_callbacks(cpu);
- if ( (pending = softirq_pending(cpu)) == 0 )
+ if ( (pending = (softirq_pending(cpu) & ~ignore_mask)) == 0 )
break;
i = find_first_set_bit(pending);
@@ -47,6 +47,18 @@ asmlinkage void do_softirq(void)
}
}
+void process_pending_softirqs(void)
+{
+ ASSERT(!in_irq() && local_irq_is_enabled());
+ /* Do not enter scheduler as it can preempt the calling context. */
+ __do_softirq(1ul<<SCHEDULE_SOFTIRQ);
+}
+
+asmlinkage void do_softirq(void)
+{
+ __do_softirq(0);
+}
+
void open_softirq(int nr, softirq_handler handler)
{
softirq_handlers[nr] = handler;
--- a/xen/common/timer.c
+++ b/xen/common/timer.c
@@ -438,15 +438,6 @@ 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;
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -657,7 +657,7 @@ void __init console_endboot(void)
printk("%d... ", 3-i);
for ( j = 0; j < 100; j++ )
{
- process_pending_timers();
+ process_pending_softirqs();
mdelay(10);
}
}
--- a/xen/include/xen/softirq.h
+++ b/xen/include/xen/softirq.h
@@ -54,6 +54,13 @@ static inline void raise_softirq(unsigne
}
/*
+ * Process pending softirqs on this CPU. This should be called periodically
+ * when performing work that prevents softirqs from running in a timely manner.
+ * Use this instead of do_softirq() when you do not want to be preempted.
+ */
+void process_pending_softirqs(void);
+
+/*
* TASKLETS -- dynamically-allocatable tasks run in softirq context
* on at most one CPU at a time.
*/
--- a/xen/include/xen/timer.h
+++ b/xen/include/xen/timer.h
@@ -102,12 +102,6 @@ extern void migrate_timer(struct timer *
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);