ia64/xen-unstable

changeset 626:384fbe1ed716

bitkeeper revision 1.339.1.11 (3f132035CGTz70qQug_kGM8wm0k5gw)

dev.c, xen_block.c, kernel.c, setup.c, nmi.c:
Fixed deadlock race in network code. Watchdog timer is now disabled by default. Improved tracing in Xen blkdev code.
author kaf24@scramble.cl.cam.ac.uk
date Mon Jul 14 21:27:17 2003 +0000 (2003-07-14)
parents e57f48a3d5fb
children a74ec9013abb 6d07235a19e8
files xen/arch/i386/nmi.c xen/arch/i386/setup.c xen/common/kernel.c xen/drivers/block/xen_block.c xen/net/dev.c
line diff
     1.1 --- a/xen/arch/i386/nmi.c	Mon Jul 14 16:44:58 2003 +0000
     1.2 +++ b/xen/arch/i386/nmi.c	Mon Jul 14 21:27:17 2003 +0000
     1.3 @@ -27,10 +27,7 @@
     1.4  #include <asm/msr.h>
     1.5  #include <asm/mpspec.h>
     1.6  
     1.7 -#undef Dprintk
     1.8 -#define Dprintk(x...) printk(x)
     1.9 -
    1.10 -unsigned int nmi_watchdog = NMI_LOCAL_APIC;
    1.11 +unsigned int nmi_watchdog = NMI_NONE;
    1.12  static unsigned int nmi_hz = HZ;
    1.13  unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
    1.14  extern void show_registers(struct pt_regs *regs);
    1.15 @@ -80,6 +77,9 @@ int __init check_nmi_watchdog (void)
    1.16      unsigned int prev_nmi_count[NR_CPUS];
    1.17      int j, cpu;
    1.18      
    1.19 +    if (!nmi_watchdog)
    1.20 +        return 0;
    1.21 +
    1.22      printk("testing NMI watchdog ---\n");
    1.23  
    1.24      for (j = 0; j < smp_num_cpus; j++) {
    1.25 @@ -197,6 +197,9 @@ static int __pminit setup_p4_watchdog(vo
    1.26  
    1.27  void __pminit setup_apic_nmi_watchdog (void)
    1.28  {
    1.29 +    if (!nmi_watchdog)
    1.30 +        return;
    1.31 +
    1.32      switch (boot_cpu_data.x86_vendor) {
    1.33      case X86_VENDOR_AMD:
    1.34          if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15)
     2.1 --- a/xen/arch/i386/setup.c	Mon Jul 14 16:44:58 2003 +0000
     2.2 +++ b/xen/arch/i386/setup.c	Mon Jul 14 21:27:17 2003 +0000
     2.3 @@ -286,17 +286,20 @@ void __init start_of_day(void)
     2.4      extern void tqueue_bh(void);
     2.5      extern void immediate_bh(void);
     2.6      extern void init_timervecs(void);
     2.7 -	extern void disable_pit(void);
     2.8 -	extern void ac_timer_init(void);
     2.9 +    extern void disable_pit(void);
    2.10 +    extern void ac_timer_init(void);
    2.11      extern int  setup_network_devices(void);
    2.12      extern void net_init(void);
    2.13      extern void initialize_block_io(void);
    2.14      extern void initialize_keytable(); 
    2.15      extern void initialize_serial(void);
    2.16      extern void initialize_keyboard(void);
    2.17 -    extern int opt_nosmp;
    2.18 +    extern int opt_nosmp, opt_watchdog;
    2.19      unsigned long low_mem_size;
    2.20      
    2.21 +    if ( opt_watchdog ) 
    2.22 +        nmi_watchdog = NMI_LOCAL_APIC;
    2.23 +
    2.24      /*
    2.25       * We do this early, but tables are in the lowest 1MB (usually
    2.26       * 0xfe000-0xfffff). Therefore they're unlikely to ever get clobbered.
     3.1 --- a/xen/common/kernel.c	Mon Jul 14 16:44:58 2003 +0000
     3.2 +++ b/xen/common/kernel.c	Mon Jul 14 21:27:17 2003 +0000
     3.3 @@ -41,7 +41,7 @@ unsigned int opt_ser_baud = 9600;  /* de
     3.4  unsigned int opt_dom0_mem = 16000; /* default kbytes for DOM0 */
     3.5  unsigned int opt_ne_base = 0; /* NE2k NICs cannot be probed */
     3.6  unsigned char opt_ifname[10] = "eth0";
     3.7 -int opt_noht=0, opt_noacpi=0, opt_nosmp=0;
     3.8 +int opt_noht=0, opt_noacpi=0, opt_nosmp=0, opt_watchdog=0;
     3.9  enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL };
    3.10  static struct {
    3.11      unsigned char *name;
    3.12 @@ -56,6 +56,7 @@ static struct {
    3.13      { "noht",        OPT_BOOL, &opt_noht },
    3.14      { "noacpi",      OPT_BOOL, &opt_noacpi },
    3.15      { "nosmp",       OPT_BOOL, &opt_nosmp },
    3.16 +    { "watchdog",    OPT_BOOL, &opt_watchdog },
    3.17      { NULL,       0,        NULL     }
    3.18  };
    3.19  
     4.1 --- a/xen/drivers/block/xen_block.c	Mon Jul 14 16:44:58 2003 +0000
     4.2 +++ b/xen/drivers/block/xen_block.c	Mon Jul 14 21:27:17 2003 +0000
     4.3 @@ -704,14 +704,14 @@ static void dispatch_rw_block_io(struct 
     4.4              phys_seg[nr_psegs].nr_sects      = nr_sects;
     4.5  	    if (p->domain != 0 &&
     4.6  		!xen_physdisk_access_okay(&phys_seg[nr_psegs], p, operation)) {
     4.7 -	      DPRINTK("access denied\n");
     4.8 -	      /* XXX not quite right, but close enough. */
     4.9 -	      goto bad_descriptor;
    4.10 +                DPRINTK("access denied: dev=%04x off=%ld nr=%ld\n",
    4.11 +                        req->device, req->sector_number + tot_sects, nr_sects);
    4.12 +                goto bad_descriptor;
    4.13  	    }
    4.14  	    phys_seg[nr_psegs].dev           = xendev_to_physdev(req->device);
    4.15              if ( phys_seg[nr_psegs].dev == 0 ) 
    4.16  	    {
    4.17 -	        DPRINTK("bad device\n");
    4.18 +	        DPRINTK("bad device: %04x\n", req_device);
    4.19  	        goto bad_descriptor;
    4.20  	    }
    4.21              new_segs = 1;
     5.1 --- a/xen/net/dev.c	Mon Jul 14 16:44:58 2003 +0000
     5.2 +++ b/xen/net/dev.c	Mon Jul 14 21:27:17 2003 +0000
     5.3 @@ -1768,7 +1768,7 @@ long do_net_update(void)
     5.4      net_vif_t *vif;
     5.5      net_idx_t *shared_idxs;
     5.6      unsigned int i, j, idx;
     5.7 -    struct sk_buff *skb;
     5.8 +    struct sk_buff *skb, *interdom_skb = NULL;
     5.9      tx_req_entry_t tx;
    5.10      rx_req_entry_t rx;
    5.11      unsigned long pte_pfn, buf_pfn;
    5.12 @@ -1889,7 +1889,11 @@ long do_net_update(void)
    5.13                  skb->len = tx.size - ETH_HLEN;
    5.14                  unmap_domain_mem(skb->head);
    5.15  
    5.16 -                (void)netif_rx(skb);
    5.17 +                /*
    5.18 +                 * We must defer netif_rx until we have released the current
    5.19 +                 * domain's page_lock, or we may deadlock on SMP.
    5.20 +                 */
    5.21 +                interdom_skb = skb;
    5.22  
    5.23                  make_tx_response(vif, tx.id, RING_STATUS_OK);
    5.24              }
    5.25 @@ -1897,6 +1901,11 @@ long do_net_update(void)
    5.26          tx_unmap_and_continue:
    5.27              unmap_domain_mem(g_data);
    5.28              spin_unlock_irq(&current->page_lock);
    5.29 +            if ( interdom_skb != NULL )
    5.30 +            {
    5.31 +                (void)netif_rx(interdom_skb);
    5.32 +                interdom_skb = NULL;
    5.33 +            }
    5.34          }
    5.35  
    5.36          vif->tx_req_cons = i;