direct-io.hg

changeset 10565:53f552ad4042

[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>
author kfraser@dhcp93.uk.xensource.com
date Fri Jun 30 13:25:43 2006 +0100 (2006-06-30)
parents 129ce4f59b6d
children 9dbcf482f600
files xen/arch/x86/domain.c xen/arch/x86/smpboot.c xen/common/page_alloc.c xen/common/softirq.c xen/common/timer.c xen/drivers/char/console.c xen/include/xen/timer.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Fri Jun 30 10:35:54 2006 +0100
     1.2 +++ b/xen/arch/x86/domain.c	Fri Jun 30 13:25:43 2006 +0100
     1.3 @@ -67,16 +67,11 @@ static void default_idle(void)
     1.4  
     1.5  void idle_loop(void)
     1.6  {
     1.7 -    int cpu = smp_processor_id();
     1.8 -
     1.9      for ( ; ; )
    1.10      {
    1.11          page_scrub_schedule_work();
    1.12 -
    1.13          default_idle();
    1.14 -
    1.15 -        if ( softirq_pending(cpu) )
    1.16 -            do_softirq();
    1.17 +        do_softirq();
    1.18      }
    1.19  }
    1.20  
     2.1 --- a/xen/arch/x86/smpboot.c	Fri Jun 30 10:35:54 2006 +0100
     2.2 +++ b/xen/arch/x86/smpboot.c	Fri Jun 30 13:25:43 2006 +0100
     2.3 @@ -1197,8 +1197,7 @@ int __devinit __cpu_up(unsigned int cpu)
     2.4  	cpu_set(cpu, smp_commenced_mask);
     2.5  	while (!cpu_isset(cpu, cpu_online_map)) {
     2.6  		mb();
     2.7 -		if (softirq_pending(0))
     2.8 -			do_softirq();
     2.9 +		process_pending_timers();
    2.10  	}
    2.11  	return 0;
    2.12  }
     3.1 --- a/xen/common/page_alloc.c	Fri Jun 30 10:35:54 2006 +0100
     3.2 +++ b/xen/common/page_alloc.c	Fri Jun 30 13:25:43 2006 +0100
     3.3 @@ -388,7 +388,6 @@ void scrub_heap_pages(void)
     3.4  {
     3.5      void *p;
     3.6      unsigned long pfn;
     3.7 -    int cpu = smp_processor_id();
     3.8  
     3.9      printk("Scrubbing Free RAM: ");
    3.10  
    3.11 @@ -398,8 +397,7 @@ void scrub_heap_pages(void)
    3.12          if ( (pfn % ((100*1024*1024)/PAGE_SIZE)) == 0 )
    3.13              printk(".");
    3.14  
    3.15 -        if ( unlikely(softirq_pending(cpu)) )
    3.16 -            do_softirq();
    3.17 +        process_pending_timers();
    3.18  
    3.19          /* Quick lock-free check. */
    3.20          if ( allocated_in_map(pfn) )
     4.1 --- a/xen/common/softirq.c	Fri Jun 30 10:35:54 2006 +0100
     4.2 +++ b/xen/common/softirq.c	Fri Jun 30 13:25:43 2006 +0100
     4.3 @@ -23,17 +23,23 @@ static softirq_handler softirq_handlers[
     4.4  
     4.5  asmlinkage void do_softirq(void)
     4.6  {
     4.7 -    unsigned int i, cpu = smp_processor_id();
     4.8 +    unsigned int i, cpu;
     4.9      unsigned long pending;
    4.10  
    4.11 -    pending = softirq_pending(cpu);
    4.12 -    ASSERT(pending != 0);
    4.13 +    for ( ; ; )
    4.14 +    {
    4.15 +        /*
    4.16 +         * Initialise @cpu on every iteration: SCHEDULE_SOFTIRQ may move
    4.17 +         * us to another processor.
    4.18 +         */
    4.19 +        cpu = smp_processor_id();
    4.20 +        if ( (pending = softirq_pending(cpu)) == 0 )
    4.21 +            break;
    4.22  
    4.23 -    do {
    4.24          i = find_first_set_bit(pending);
    4.25          clear_bit(i, &softirq_pending(cpu));
    4.26          (*softirq_handlers[i])();
    4.27 -    } while ( (pending = softirq_pending(cpu)) != 0 );
    4.28 +    }
    4.29  }
    4.30  
    4.31  void open_softirq(int nr, softirq_handler handler)
     5.1 --- a/xen/common/timer.c	Fri Jun 30 10:35:54 2006 +0100
     5.2 +++ b/xen/common/timer.c	Fri Jun 30 13:25:43 2006 +0100
     5.3 @@ -327,6 +327,15 @@ static void timer_softirq_action(void)
     5.4  }
     5.5  
     5.6  
     5.7 +void process_pending_timers(void)
     5.8 +{
     5.9 +    unsigned int cpu = smp_processor_id();
    5.10 +    ASSERT(!in_irq() && local_irq_is_enabled());
    5.11 +    if ( test_and_clear_bit(TIMER_SOFTIRQ, &softirq_pending(cpu)) )
    5.12 +        timer_softirq_action();
    5.13 +}
    5.14 +
    5.15 +
    5.16  static void dump_timerq(unsigned char key)
    5.17  {
    5.18      struct timer *t;
     6.1 --- a/xen/drivers/char/console.c	Fri Jun 30 10:35:54 2006 +0100
     6.2 +++ b/xen/drivers/char/console.c	Fri Jun 30 13:25:43 2006 +0100
     6.3 @@ -528,8 +528,7 @@ void console_endboot(void)
     6.4              printk("%d... ", 3-i);
     6.5              for ( j = 0; j < 100; j++ )
     6.6              {
     6.7 -                if ( softirq_pending(smp_processor_id()) )
     6.8 -                    do_softirq();
     6.9 +                process_pending_timers();
    6.10                  mdelay(10);
    6.11              }
    6.12          }
     7.1 --- a/xen/include/xen/timer.h	Fri Jun 30 10:35:54 2006 +0100
     7.2 +++ b/xen/include/xen/timer.h	Fri Jun 30 13:25:43 2006 +0100
     7.3 @@ -89,6 +89,12 @@ extern void migrate_timer(struct timer *
     7.4  extern void kill_timer(struct timer *timer);
     7.5  
     7.6  /*
     7.7 + * Process pending timers on this CPU. This should be called periodically
     7.8 + * when performing work that prevents softirqs from running in a timely manner.
     7.9 + */
    7.10 +extern void process_pending_timers(void);
    7.11 +
    7.12 +/*
    7.13   * Bootstrap initialisation. Must be called before any other timer function.
    7.14   */
    7.15  extern void timer_init(void);