mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[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@xensource.com>
This commit is contained in:
1 parent
0968f0be1f
commit
ae9bfcdced
7 files changed
+30
-18
No files matched your search
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) )
|
||||
|
||||
+11
-5
@@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[NR_SOFTIRQS];
|
||||
|
||||
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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,12 @@ extern void migrate_timer(struct timer *timer, unsigned int new_cpu);
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||