direct-io.hg

changeset 1776:c2f673cea5e4

bitkeeper revision 1.1072.1.1 (40f4e51fLMgcKX4Sn6FNYePX6EqkGA)

Merge http://xen.bkbits.net:8080/xeno-unstable.bk
into gandalf.hpl.hp.com:/var/bk/xeno-unstable.bk
author xenbk@gandalf.hpl.hp.com
date Wed Jul 14 07:47:43 2004 +0000 (2004-07-14)
parents b9fc18608f2b ad09d919356e
children e91945007886
files README.CD docs/HOWTOs/Xen-HOWTO linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c tools/examples/init.d/xend tools/python/xen/xend/XendRoot.py xen/arch/x86/domain.c xen/arch/x86/x86_32/mm.c xen/common/kernel.c xen/drivers/char/console.c xen/include/asm-x86/config.h xen/include/asm-x86/mm.h
line diff
     1.1 --- a/README.CD	Tue Jul 13 09:04:27 2004 +0000
     1.2 +++ b/README.CD	Wed Jul 14 07:47:43 2004 +0000
     1.3 @@ -307,6 +307,16 @@ that may be able to help diagnose proble
     1.4                    transmitted/received character.
     1.5   [NB. Default for this option is 'com1,tty']
     1.6  
     1.7 + conswitch=<switch-char><auto-switch-char>
     1.8 +                  Specify how to switch serial-console input between
     1.9 +                  Xen and DOM0. The required sequence is CTRL-<switch_char>
    1.10 +                  pressed three times. Specifying '`' disables switching.
    1.11 +                  The <auto-switch-char> specifies whether Xen should
    1.12 +                  auto-switch input to DOM0 when it boots -- if it is 'x'
    1.13 +                  then auto-switching is disabled. Any other value, or
    1.14 +                  omitting the character, enables auto-switching.
    1.15 + [NB. Default for this option is 'a']
    1.16 +
    1.17   dom0_mem=xxx 	  Set the initial amount of memory for domain0.
    1.18  
    1.19   pdb=xxx          Enable the pervasive debugger.  See docs/pdb.txt
     2.1 --- a/docs/HOWTOs/Xen-HOWTO	Tue Jul 13 09:04:27 2004 +0000
     2.2 +++ b/docs/HOWTOs/Xen-HOWTO	Wed Jul 14 07:47:43 2004 +0000
     2.3 @@ -253,6 +253,16 @@ The following is a list of command line 
     2.4                    transmitted/received character.
     2.5   [NB. Default for this option is 'com1,tty']
     2.6  
     2.7 + conswitch=<switch-char><auto-switch-char>
     2.8 +                  Specify how to switch serial-console input between
     2.9 +                  Xen and DOM0. The required sequence is CTRL-<switch_char>
    2.10 +                  pressed three times. Specifying '`' disables switching.
    2.11 +                  The <auto-switch-char> specifies whether Xen should
    2.12 +                  auto-switch input to DOM0 when it boots -- if it is 'x'
    2.13 +                  then auto-switching is disabled. Any other value, or
    2.14 +                  omitting the character, enables auto-switching.
    2.15 + [NB. Default for this option is 'a']
    2.16 +
    2.17   dom0_mem=xxx     Set the maximum amount of memory for domain0.
    2.18  
    2.19   tbuf_size=xxx    Set the size of the per-cpu trace buffers, in pages
     3.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c	Tue Jul 13 09:04:27 2004 +0000
     3.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/main.c	Wed Jul 14 07:47:43 2004 +0000
     3.3 @@ -141,30 +141,44 @@ static void add_to_blkdev_list_tail(blki
     3.4   * SCHEDULER FUNCTIONS
     3.5   */
     3.6  
     3.7 -static void io_schedule(unsigned long unused)
     3.8 +static DECLARE_WAIT_QUEUE_HEAD(io_schedule_wait);
     3.9 +
    3.10 +static int io_schedule(void *arg)
    3.11  {
    3.12 +    DECLARE_WAITQUEUE(wq, current);
    3.13 +
    3.14      blkif_t          *blkif;
    3.15      struct list_head *ent;
    3.16  
    3.17 -    /* Queue up a batch of requests. */
    3.18 -    while ( (NR_PENDING_REQS < MAX_PENDING_REQS) &&
    3.19 -            !list_empty(&io_schedule_list) )
    3.20 +    for ( ; ; )
    3.21      {
    3.22 -        ent = io_schedule_list.next;
    3.23 -        blkif = list_entry(ent, blkif_t, blkdev_list);
    3.24 -        blkif_get(blkif);
    3.25 -        remove_from_blkdev_list(blkif);
    3.26 -        if ( do_block_io_op(blkif, BATCH_PER_DOMAIN) )
    3.27 -            add_to_blkdev_list_tail(blkif);
    3.28 -        blkif_put(blkif);
    3.29 +        /* Wait for work to do. */
    3.30 +        add_wait_queue(&io_schedule_wait, &wq);
    3.31 +        set_current_state(TASK_INTERRUPTIBLE);
    3.32 +        if ( (NR_PENDING_REQS == MAX_PENDING_REQS) || 
    3.33 +             list_empty(&io_schedule_list) )
    3.34 +            schedule();
    3.35 +        __set_current_state(TASK_RUNNING);
    3.36 +        remove_wait_queue(&io_schedule_wait, &wq);
    3.37 +
    3.38 +        /* Queue up a batch of requests. */
    3.39 +        while ( (NR_PENDING_REQS < MAX_PENDING_REQS) &&
    3.40 +                !list_empty(&io_schedule_list) )
    3.41 +        {
    3.42 +            ent = io_schedule_list.next;
    3.43 +            blkif = list_entry(ent, blkif_t, blkdev_list);
    3.44 +            blkif_get(blkif);
    3.45 +            remove_from_blkdev_list(blkif);
    3.46 +            if ( do_block_io_op(blkif, BATCH_PER_DOMAIN) )
    3.47 +                add_to_blkdev_list_tail(blkif);
    3.48 +            blkif_put(blkif);
    3.49 +        }
    3.50 +        
    3.51 +        /* Push the batch through to disc. */
    3.52 +        run_task_queue(&tq_disk);
    3.53      }
    3.54 -
    3.55 -    /* Push the batch through to disc. */
    3.56 -    run_task_queue(&tq_disk);
    3.57  }
    3.58  
    3.59 -static DECLARE_TASKLET(io_schedule_tasklet, io_schedule, 0);
    3.60 -
    3.61  static void maybe_trigger_io_schedule(void)
    3.62  {
    3.63      /*
    3.64 @@ -176,7 +190,7 @@ static void maybe_trigger_io_schedule(vo
    3.65  
    3.66      if ( (NR_PENDING_REQS < (MAX_PENDING_REQS/2)) &&
    3.67           !list_empty(&io_schedule_list) )
    3.68 -        tasklet_schedule(&io_schedule_tasklet);
    3.69 +        wake_up(&io_schedule_wait);
    3.70  }
    3.71  
    3.72  
    3.73 @@ -483,7 +497,7 @@ void blkif_deschedule(blkif_t *blkif)
    3.74      remove_from_blkdev_list(blkif);
    3.75  }
    3.76  
    3.77 -static int __init init_module(void)
    3.78 +static int __init blkif_init(void)
    3.79  {
    3.80      int i;
    3.81  
    3.82 @@ -505,6 +519,9 @@ static int __init init_module(void)
    3.83      spin_lock_init(&io_schedule_list_lock);
    3.84      INIT_LIST_HEAD(&io_schedule_list);
    3.85  
    3.86 +    if ( kernel_thread(io_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
    3.87 +        BUG();
    3.88 +
    3.89      buffer_head_cachep = kmem_cache_create(
    3.90          "buffer_head_cache", sizeof(struct buffer_head),
    3.91          0, SLAB_HWCACHE_ALIGN, NULL, NULL);
    3.92 @@ -514,10 +531,4 @@ static int __init init_module(void)
    3.93      return 0;
    3.94  }
    3.95  
    3.96 -static void cleanup_module(void)
    3.97 -{
    3.98 -    BUG();
    3.99 -}
   3.100 -
   3.101 -module_init(init_module);
   3.102 -module_exit(cleanup_module);
   3.103 +__initcall(blkif_init);
     4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c	Tue Jul 13 09:04:27 2004 +0000
     4.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c	Wed Jul 14 07:47:43 2004 +0000
     4.3 @@ -1,7 +1,7 @@
     4.4  /******************************************************************************
     4.5   * arch/xen/drivers/netif/frontend/main.c
     4.6   * 
     4.7 - * Virtual network driver for XenoLinux.
     4.8 + * Virtual network driver for conversing with remote driver backends.
     4.9   * 
    4.10   * Copyright (c) 2002-2004, K A Fraser
    4.11   */
    4.12 @@ -36,7 +36,6 @@
    4.13  
    4.14  static void network_tx_buf_gc(struct net_device *dev);
    4.15  static void network_alloc_rx_buffers(struct net_device *dev);
    4.16 -static void cleanup_module(void);
    4.17  
    4.18  static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE];
    4.19  static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
    4.20 @@ -63,11 +62,16 @@ struct net_private
    4.21      unsigned int evtchn;
    4.22      unsigned int irq;
    4.23  
    4.24 -#define NETIF_STATE_CLOSED       0
    4.25 -#define NETIF_STATE_DISCONNECTED 1
    4.26 -#define NETIF_STATE_CONNECTED    2
    4.27 -#define NETIF_STATE_ACTIVE       3
    4.28 -    unsigned int state;
    4.29 +    /* What is the status of our connection to the remote backend? */
    4.30 +#define BEST_CLOSED       0
    4.31 +#define BEST_DISCONNECTED 1
    4.32 +#define BEST_CONNECTED    2
    4.33 +    unsigned int backend_state;
    4.34 +
    4.35 +    /* Is this interface open or closed (down or up)? */
    4.36 +#define UST_CLOSED        0
    4.37 +#define UST_OPEN          1
    4.38 +    unsigned int user_state;
    4.39  
    4.40      /*
    4.41       * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
    4.42 @@ -135,7 +139,8 @@ static int netctrl_err(int err)
    4.43  static int netctrl_connected(void)
    4.44  {
    4.45      int ok = 0;
    4.46 -    ok = (netctrl.err ? netctrl.err : (netctrl.connected_n == netctrl.interface_n));
    4.47 +    ok = (netctrl.err ? netctrl.err :
    4.48 +          (netctrl.connected_n == netctrl.interface_n));
    4.49      return ok;
    4.50  }
    4.51  
    4.52 @@ -152,12 +157,13 @@ static int netctrl_connected_count(void)
    4.53  
    4.54      connected = 0;
    4.55      
    4.56 -    list_for_each(ent, &dev_list) {
    4.57 +    list_for_each(ent, &dev_list)
    4.58 +    {
    4.59          np = list_entry(ent, struct net_private, list);
    4.60 -        if ( np->state == NETIF_STATE_CONNECTED){
    4.61 +        if ( np->backend_state == BEST_CONNECTED )
    4.62              connected++;
    4.63 -        }
    4.64      }
    4.65 +
    4.66      netctrl.connected_n = connected;
    4.67      return connected;
    4.68  }
    4.69 @@ -165,32 +171,16 @@ static int netctrl_connected_count(void)
    4.70  static int network_open(struct net_device *dev)
    4.71  {
    4.72      struct net_private *np = dev->priv;
    4.73 -    int i;
    4.74  
    4.75 -    if ( np->state != NETIF_STATE_CONNECTED )
    4.76 -        return -EINVAL;
    4.77 -
    4.78 -    np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
    4.79      memset(&np->stats, 0, sizeof(np->stats));
    4.80 -    spin_lock_init(&np->tx_lock);
    4.81 -    spin_lock_init(&np->rx_lock);
    4.82  
    4.83 -    /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
    4.84 -    for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ )
    4.85 -        np->tx_skbs[i] = (void *)(i+1);
    4.86 -    for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ )
    4.87 -        np->rx_skbs[i] = (void *)(i+1);
    4.88 -
    4.89 -    wmb();
    4.90 -    np->state = NETIF_STATE_ACTIVE;
    4.91 +    np->user_state = UST_OPEN;
    4.92  
    4.93      network_alloc_rx_buffers(dev);
    4.94      np->rx->event = np->rx_resp_cons + 1;
    4.95  
    4.96      netif_start_queue(dev);
    4.97  
    4.98 -    MOD_INC_USE_COUNT;
    4.99 -
   4.100      return 0;
   4.101  }
   4.102  
   4.103 @@ -202,6 +192,9 @@ static void network_tx_buf_gc(struct net
   4.104      struct net_private *np = dev->priv;
   4.105      struct sk_buff *skb;
   4.106  
   4.107 +    if ( np->backend_state != BEST_CONNECTED )
   4.108 +        return;
   4.109 +
   4.110      do {
   4.111          prod = np->tx->resp_prod;
   4.112  
   4.113 @@ -233,7 +226,7 @@ static void network_tx_buf_gc(struct net
   4.114           ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE) )
   4.115      {
   4.116          np->tx_full = 0;
   4.117 -        if ( np->state == NETIF_STATE_ACTIVE )
   4.118 +        if ( np->user_state == UST_OPEN )
   4.119              netif_wake_queue(dev);
   4.120      }
   4.121  }
   4.122 @@ -249,7 +242,7 @@ static void network_alloc_rx_buffers(str
   4.123  
   4.124      /* Make sure the batch is large enough to be worthwhile (1/2 ring). */
   4.125      if ( unlikely((i - np->rx_resp_cons) > (NETIF_RX_RING_SIZE/2)) || 
   4.126 -         unlikely(np->state != NETIF_STATE_ACTIVE) )
   4.127 +         unlikely(np->backend_state != BEST_CONNECTED) )
   4.128          return;
   4.129  
   4.130      do {
   4.131 @@ -333,8 +326,7 @@ static int network_start_xmit(struct sk_
   4.132      
   4.133      spin_lock_irq(&np->tx_lock);
   4.134  
   4.135 -    /* if the backend isn't available then don't do anything! */
   4.136 -    if ( !netif_carrier_ok(dev) )
   4.137 +    if ( np->backend_state != BEST_CONNECTED )
   4.138      {
   4.139          spin_unlock_irq(&np->tx_lock);
   4.140          return 1;
   4.141 @@ -383,11 +375,11 @@ static void netif_int(int irq, void *dev
   4.142      unsigned long flags;
   4.143  
   4.144      spin_lock_irqsave(&np->tx_lock, flags);
   4.145 -    if ( likely(netif_carrier_ok(dev)) )
   4.146 -        network_tx_buf_gc(dev);
   4.147 +    network_tx_buf_gc(dev);
   4.148      spin_unlock_irqrestore(&np->tx_lock, flags);
   4.149  
   4.150 -    if ( np->rx_resp_cons != np->rx->resp_prod )
   4.151 +    if ( (np->rx_resp_cons != np->rx->resp_prod) &&
   4.152 +         (np->user_state == UST_OPEN) )
   4.153          netif_rx_schedule(dev);
   4.154  }
   4.155  
   4.156 @@ -406,8 +398,7 @@ static int netif_poll(struct net_device 
   4.157  
   4.158      spin_lock(&np->rx_lock);
   4.159  
   4.160 -    /* If the device is undergoing recovery then don't do anything. */
   4.161 -    if ( !netif_carrier_ok(dev) )
   4.162 +    if ( np->backend_state != BEST_CONNECTED )
   4.163      {
   4.164          spin_unlock(&np->rx_lock);
   4.165          return 0;
   4.166 @@ -430,7 +421,7 @@ static int netif_poll(struct net_device 
   4.167          if ( unlikely(rx->status <= 0) )
   4.168          {
   4.169              /* Gate this error. We get a (valid) slew of them on suspend. */
   4.170 -            if ( np->state == NETIF_STATE_ACTIVE )
   4.171 +            if ( np->user_state != UST_OPEN )
   4.172                  printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
   4.173              dev_kfree_skb(skb);
   4.174              continue;
   4.175 @@ -517,22 +508,8 @@ static int netif_poll(struct net_device 
   4.176  static int network_close(struct net_device *dev)
   4.177  {
   4.178      struct net_private *np = dev->priv;
   4.179 -
   4.180 +    np->user_state = UST_CLOSED;
   4.181      netif_stop_queue(np->dev);
   4.182 -
   4.183 -    np->state = NETIF_STATE_CONNECTED;
   4.184 -
   4.185 -    /* XXX We need to properly disconnect via the domain controller. */
   4.186 -    while ( /*(np->rx_resp_cons != np->rx->req_prod) ||*/
   4.187 -            (np->tx_resp_cons != np->tx->req_prod) )
   4.188 -    {
   4.189 -        barrier();
   4.190 -        current->state = TASK_INTERRUPTIBLE;
   4.191 -        schedule_timeout(1);
   4.192 -    }
   4.193 -
   4.194 -    MOD_DEC_USE_COUNT;
   4.195 -
   4.196      return 0;
   4.197  }
   4.198  
   4.199 @@ -544,7 +521,8 @@ static struct net_device_stats *network_
   4.200  }
   4.201  
   4.202  
   4.203 -static void network_reconnect(struct net_device *dev, netif_fe_interface_status_changed_t *status)
   4.204 +static void network_connect(struct net_device *dev,
   4.205 +                            netif_fe_interface_status_changed_t *status)
   4.206  {
   4.207      struct net_private *np;
   4.208      int i, requeue_idx;
   4.209 @@ -576,8 +554,10 @@ static void network_reconnect(struct net
   4.210       * to avoid this but maybe it doesn't matter so much given the
   4.211       * interface has been down.
   4.212       */
   4.213 -    for( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ ){
   4.214 -            if( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET ) {
   4.215 +    for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ )
   4.216 +    {
   4.217 +            if ( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET )
   4.218 +            {
   4.219                  struct sk_buff *skb = np->tx_skbs[i];
   4.220                  
   4.221                  tx = &np->tx->ring[requeue_idx++].req;
   4.222 @@ -605,15 +585,12 @@ static void network_reconnect(struct net
   4.223       * domain a kick because we've probably just requeued some
   4.224       * packets.
   4.225       */
   4.226 -    netif_carrier_on(dev);
   4.227 -    netif_start_queue(dev);
   4.228 -    np->state = NETIF_STATE_ACTIVE;
   4.229 -
   4.230 +    np->backend_state = BEST_CONNECTED;
   4.231      notify_via_evtchn(status->evtchn);  
   4.232 -
   4.233      network_tx_buf_gc(dev);
   4.234  
   4.235 -    printk(KERN_INFO "Recovery completed\n");
   4.236 +    if ( np->user_state == UST_OPEN )
   4.237 +        netif_start_queue(dev);
   4.238  
   4.239      spin_unlock(&np->tx_lock);
   4.240      spin_unlock_irq(&np->rx_lock);
   4.241 @@ -644,14 +621,14 @@ static void netif_status_change(netif_fe
   4.242      {
   4.243      case NETIF_INTERFACE_STATUS_DESTROYED:
   4.244          printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n",
   4.245 -               np->state);
   4.246 +               np->backend_state);
   4.247          break;
   4.248  
   4.249      case NETIF_INTERFACE_STATUS_DISCONNECTED:
   4.250 -        if ( np->state != NETIF_STATE_CLOSED )
   4.251 +        if ( np->backend_state != BEST_CLOSED )
   4.252          {
   4.253              printk(KERN_WARNING "Unexpected netif-DISCONNECTED message"
   4.254 -                   " in state %d\n", np->state);
   4.255 +                   " in state %d\n", np->backend_state);
   4.256  	    printk(KERN_INFO "Attempting to reconnect network interface\n");
   4.257  
   4.258              /* Begin interface recovery.
   4.259 @@ -672,8 +649,7 @@ static void netif_status_change(netif_fe
   4.260              spin_lock_irq(&np->tx_lock);
   4.261              spin_lock(&np->rx_lock);
   4.262              netif_stop_queue(dev);
   4.263 -            netif_carrier_off(dev);
   4.264 -            np->state  = NETIF_STATE_DISCONNECTED;
   4.265 +            np->backend_state = BEST_DISCONNECTED;
   4.266              spin_unlock(&np->rx_lock);
   4.267              spin_unlock_irq(&np->tx_lock);
   4.268  
   4.269 @@ -689,7 +665,7 @@ static void netif_status_change(netif_fe
   4.270          np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
   4.271          memset(np->tx, 0, PAGE_SIZE);
   4.272          memset(np->rx, 0, PAGE_SIZE);
   4.273 -        np->state  = NETIF_STATE_DISCONNECTED;
   4.274 +        np->backend_state = BEST_DISCONNECTED;
   4.275  
   4.276          /* Construct an interface-CONNECT message for the domain controller. */
   4.277          cmsg.type      = CMSG_NETIF_FE;
   4.278 @@ -705,18 +681,16 @@ static void netif_status_change(netif_fe
   4.279          break;
   4.280  
   4.281      case NETIF_INTERFACE_STATUS_CONNECTED:
   4.282 -        if ( np->state == NETIF_STATE_CLOSED ){
   4.283 +        if ( np->backend_state == BEST_CLOSED )
   4.284 +        {
   4.285              printk(KERN_WARNING "Unexpected netif-CONNECTED message"
   4.286 -                   " in state %d\n", np->state);
   4.287 +                   " in state %d\n", np->backend_state);
   4.288              break;
   4.289          }
   4.290  
   4.291          memcpy(dev->dev_addr, status->mac, ETH_ALEN);
   4.292  
   4.293 -        if ( netif_carrier_ok(dev) )
   4.294 -            np->state = NETIF_STATE_CONNECTED;
   4.295 -        else
   4.296 -            network_reconnect(dev, status);
   4.297 +        network_connect(dev, status);
   4.298  
   4.299          np->evtchn = status->evtchn;
   4.300          np->irq = bind_evtchn_to_irq(np->evtchn);
   4.301 @@ -740,20 +714,31 @@ static void netif_status_change(netif_fe
   4.302   */
   4.303  static int create_netdev(int handle, struct net_device **val)
   4.304  {
   4.305 -    int err = 0;
   4.306 +    int i, err = 0;
   4.307      struct net_device *dev = NULL;
   4.308      struct net_private *np = NULL;
   4.309  
   4.310 -    dev = alloc_etherdev(sizeof(struct net_private));
   4.311 -    if (!dev){
   4.312 +    if ( (dev = alloc_etherdev(sizeof(struct net_private))) == NULL )
   4.313 +    {
   4.314          printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__);
   4.315          err = -ENOMEM;
   4.316          goto exit;
   4.317      }
   4.318 -    np         = dev->priv;
   4.319 -    np->state  = NETIF_STATE_CLOSED;
   4.320 -    np->handle = handle;
   4.321 +
   4.322 +    np                = dev->priv;
   4.323 +    np->backend_state = BEST_CLOSED;
   4.324 +    np->user_state    = UST_CLOSED;
   4.325 +    np->handle        = handle;
   4.326      
   4.327 +    spin_lock_init(&np->tx_lock);
   4.328 +    spin_lock_init(&np->rx_lock);
   4.329 +
   4.330 +    /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
   4.331 +    for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ )
   4.332 +        np->tx_skbs[i] = (void *)(i+1);
   4.333 +    for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ )
   4.334 +        np->rx_skbs[i] = (void *)(i+1);
   4.335 +
   4.336      dev->open            = network_open;
   4.337      dev->hard_start_xmit = network_start_xmit;
   4.338      dev->stop            = network_close;
   4.339 @@ -761,19 +746,19 @@ static int create_netdev(int handle, str
   4.340      dev->poll            = netif_poll;
   4.341      dev->weight          = 64;
   4.342      
   4.343 -    err = register_netdev(dev);
   4.344 -    if (err){
   4.345 +    if ( (err = register_netdev(dev)) != 0 )
   4.346 +    {
   4.347          printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
   4.348          goto exit;
   4.349      }
   4.350      np->dev = dev;
   4.351      list_add(&np->list, &dev_list);
   4.352 +
   4.353    exit:
   4.354 -    if(err){
   4.355 -        if(dev) kfree(dev);
   4.356 -        dev = NULL;
   4.357 -    }
   4.358 -    if(val) *val = dev;
   4.359 +    if ( (err != 0) && (dev != NULL ) )
   4.360 +        kfree(dev);
   4.361 +    else if ( val != NULL )
   4.362 +        *val = dev;
   4.363      return err;
   4.364  }
   4.365  
   4.366 @@ -790,9 +775,10 @@ static void netif_driver_status_change(
   4.367      netctrl.interface_n = status->nr_interfaces;
   4.368      netctrl.connected_n = 0;
   4.369  
   4.370 -    for(i = 0; i < netctrl.interface_n; i++){
   4.371 -        err = create_netdev(i, NULL);
   4.372 -        if(err){
   4.373 +    for ( i = 0; i < netctrl.interface_n; i++ )
   4.374 +    {
   4.375 +        if ( (err = create_netdev(i, NULL)) != 0 )
   4.376 +        {
   4.377              netctrl_err(err);
   4.378              break;
   4.379          }
   4.380 @@ -832,7 +818,7 @@ static void netif_ctrlif_rx(ctrl_msg_t *
   4.381  }
   4.382  
   4.383  
   4.384 -static int __init init_module(void)
   4.385 +static int __init netif_init(void)
   4.386  {
   4.387      ctrl_msg_t                       cmsg;
   4.388      netif_fe_driver_status_changed_t st;
   4.389 @@ -878,13 +864,4 @@ static int __init init_module(void)
   4.390      return err;
   4.391  }
   4.392  
   4.393 -
   4.394 -static void cleanup_module(void)
   4.395 -{
   4.396 -    /* XXX FIXME */
   4.397 -    BUG();
   4.398 -}
   4.399 -
   4.400 -
   4.401 -module_init(init_module);
   4.402 -module_exit(cleanup_module);
   4.403 +__initcall(netif_init);
     5.1 --- a/tools/examples/init.d/xend	Tue Jul 13 09:04:27 2004 +0000
     5.2 +++ b/tools/examples/init.d/xend	Wed Jul 14 07:47:43 2004 +0000
     5.3 @@ -7,7 +7,7 @@
     5.4  # chkconfig: 2345 99 00
     5.5  # description: Starts and stops the Xen control daemon.
     5.6  
     5.7 -. /etc/init.d/functions
     5.8 +. /etc/init.d/functions || . /etc/init.d/functions.sh
     5.9  
    5.10  case "$1" in
    5.11    start)
     6.1 --- a/tools/python/xen/xend/XendRoot.py	Tue Jul 13 09:04:27 2004 +0000
     6.2 +++ b/tools/python/xen/xend/XendRoot.py	Wed Jul 14 07:47:43 2004 +0000
     6.3 @@ -17,7 +17,7 @@ import sxp
     6.4  def reboots():
     6.5      """Get a list of system reboots from wtmp.
     6.6      """
     6.7 -    out = os.popen('/usr/bin/last reboot', 'r')
     6.8 +    out = os.popen('last reboot', 'r')
     6.9      list = [ x.strip() for x in out if x.startswith('reboot') ]
    6.10      return list
    6.11  
     7.1 --- a/xen/arch/x86/domain.c	Tue Jul 13 09:04:27 2004 +0000
     7.2 +++ b/xen/arch/x86/domain.c	Wed Jul 14 07:47:43 2004 +0000
     7.3 @@ -445,12 +445,8 @@ void domain_relinquish_memory(struct dom
     7.4      struct pfn_info  *page;
     7.5      unsigned long     x, y;
     7.6  
     7.7 -    /*
     7.8 -     * If we're executing the idle task then we may still be running over the 
     7.9 -     * dead domain's page tables. We'd better fix that before freeing them!
    7.10 -     */
    7.11 -    if ( is_idle_task(current) )
    7.12 -        write_ptbase(&current->mm);
    7.13 +    /* Ensure that noone is running over the dead domain's page tables. */
    7.14 +    synchronise_pagetables(~0UL);
    7.15  
    7.16      /* Exit shadow mode before deconstructing final guest page table. */
    7.17      shadow_mode_disable(d);
     8.1 --- a/xen/arch/x86/x86_32/mm.c	Tue Jul 13 09:04:27 2004 +0000
     8.2 +++ b/xen/arch/x86/x86_32/mm.c	Wed Jul 14 07:47:43 2004 +0000
     8.3 @@ -129,6 +129,22 @@ void __init zap_low_mappings(void)
     8.4  }
     8.5  
     8.6  
     8.7 +/*
     8.8 + * Allows shooting down of borrowed page-table use on specific CPUs.
     8.9 + * Specifically, we borrow page tables when running the idle domain.
    8.10 + */
    8.11 +static void __synchronise_pagetables(void *mask)
    8.12 +{
    8.13 +    struct domain *d = current;
    8.14 +    if ( ((unsigned long)mask & (1<<d->processor)) && is_idle_task(d) )
    8.15 +        write_ptbase(&d->mm);
    8.16 +}
    8.17 +void synchronise_pagetables(unsigned long cpu_mask)
    8.18 +{
    8.19 +    __synchronise_pagetables((void *)cpu_mask);
    8.20 +    smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1);
    8.21 +}
    8.22 +
    8.23  long do_stack_switch(unsigned long ss, unsigned long esp)
    8.24  {
    8.25      int nr = smp_processor_id();
     9.1 --- a/xen/common/kernel.c	Tue Jul 13 09:04:27 2004 +0000
     9.2 +++ b/xen/common/kernel.c	Wed Jul 14 07:47:43 2004 +0000
     9.3 @@ -40,6 +40,11 @@ void start_of_day(void);
     9.4  
     9.5  /* opt_console: comma-separated list of console outputs. */
     9.6  unsigned char opt_console[30] = "com1,vga";
     9.7 +/* opt_conswitch: a character pair controlling console switching. */
     9.8 +/* Char 1: CTRL+<char1> is used to switch console input between Xen and DOM0 */
     9.9 +/* Char 2: If this character is 'x', then do not auto-switch to DOM0 when it */
    9.10 +/*         boots. Any other value, or omitting the char, enables auto-switch */
    9.11 +unsigned char opt_conswitch[5] = "a"; /* NB. '`' would disable switching. */
    9.12  /* opt_com[12]: Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
    9.13  unsigned char opt_com1[30] = "", opt_com2[30] = "";
    9.14  /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
    9.15 @@ -82,6 +87,7 @@ static struct {
    9.16      void *var;
    9.17  } opts[] = {
    9.18      { "console",           OPT_STR,  &opt_console },
    9.19 +    { "conswitch",         OPT_STR,  &opt_conswitch },
    9.20      { "com1",              OPT_STR,  &opt_com1 },
    9.21      { "com2",              OPT_STR,  &opt_com2 },
    9.22      { "dom0_mem",          OPT_UINT, &opt_dom0_mem }, 
    9.23 @@ -225,7 +231,6 @@ void cmain(unsigned long magic, multiboo
    9.24  
    9.25      init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
    9.26  
    9.27 -
    9.28  #elif defined(__x86_64__)
    9.29  
    9.30      init_frametable(__va(xenheap_phys_end), max_page);
    10.1 --- a/xen/drivers/char/console.c	Tue Jul 13 09:04:27 2004 +0000
    10.2 +++ b/xen/drivers/char/console.c	Wed Jul 14 07:47:43 2004 +0000
    10.3 @@ -17,6 +17,8 @@
    10.4  #include <xen/keyhandler.h>
    10.5  #include <asm/uaccess.h>
    10.6  
    10.7 +extern unsigned char opt_console[], opt_conswitch[];
    10.8 +
    10.9  static int xpos, ypos;
   10.10  static unsigned char *video = __va(0xB8000);
   10.11  
   10.12 @@ -227,17 +229,18 @@ long read_console_ring(unsigned long str
   10.13  static char serial_rx_ring[SERIAL_RX_SIZE];
   10.14  static unsigned int serial_rx_cons, serial_rx_prod;
   10.15  
   10.16 -/* CTRL-a switches input direction between Xen and DOM0. */
   10.17 -#define CTRL_A 0x01
   10.18 +/* CTRL-<switch_char> switches input direction between Xen and DOM0. */
   10.19 +#define SWITCH_CODE (opt_conswitch[0]-'a'+1)
   10.20  static int xen_rx = 1; /* FALSE => serial input passed to domain 0. */
   10.21  
   10.22  static void switch_serial_input(void)
   10.23  {
   10.24      static char *input_str[2] = { "DOM0", "Xen" };
   10.25      xen_rx = !xen_rx;
   10.26 -    printk("*** Serial input -> %s "
   10.27 -           "(type 'CTRL-a' three times to switch input to %s).\n",
   10.28 -           input_str[xen_rx], input_str[!xen_rx]);
   10.29 +    if ( SWITCH_CODE != 0 )
   10.30 +        printk("*** Serial input -> %s "
   10.31 +               "(type 'CTRL-%c' three times to switch input to %s).\n",
   10.32 +               input_str[xen_rx], opt_conswitch[0], input_str[!xen_rx]);
   10.33  }
   10.34  
   10.35  static void __serial_rx(unsigned char c, struct pt_regs *regs)
   10.36 @@ -264,20 +267,20 @@ static void __serial_rx(unsigned char c,
   10.37  
   10.38  static void serial_rx(unsigned char c, struct pt_regs *regs)
   10.39  {
   10.40 -    static int ctrl_a_count = 0;
   10.41 +    static int switch_code_count = 0;
   10.42  
   10.43 -    if ( c == CTRL_A )
   10.44 +    if ( (SWITCH_CODE != 0) && (c == SWITCH_CODE) )
   10.45      {
   10.46 -        /* We eat CTRL-a in groups of three to switch console input. */
   10.47 -        if ( ++ctrl_a_count == 3 )
   10.48 +        /* We eat CTRL-<switch_char> in groups of 3 to switch console input. */
   10.49 +        if ( ++switch_code_count == 3 )
   10.50          {
   10.51              switch_serial_input();
   10.52 -            ctrl_a_count = 0;
   10.53 +            switch_code_count = 0;
   10.54          }
   10.55      }
   10.56      else
   10.57      {
   10.58 -        ctrl_a_count = 0;
   10.59 +        switch_code_count = 0;
   10.60      }
   10.61  
   10.62      /* Finally process the just-received character. */
   10.63 @@ -395,7 +398,6 @@ void set_printk_prefix(const char *prefi
   10.64  
   10.65  void init_console(void)
   10.66  {
   10.67 -    extern unsigned char opt_console[];
   10.68      unsigned char *p;
   10.69  
   10.70      /* Where should console output go? */
   10.71 @@ -418,6 +420,15 @@ void console_endboot(int disable_vga)
   10.72  {
   10.73      if ( disable_vga )
   10.74          vgacon_enabled = 0;
   10.75 +
   10.76 +    /*
   10.77 +     * If user specifies so, we fool the switch routine to redirect input
   10.78 +     * straight back to Xen. I use this convoluted method so we still print
   10.79 +     * a useful 'how to switch' message.
   10.80 +     */
   10.81 +    if ( opt_conswitch[1] == 'x' )
   10.82 +        xen_rx = !xen_rx;
   10.83 +
   10.84      /* Serial input is directed to DOM0 by default. */
   10.85      switch_serial_input();
   10.86  }
    11.1 --- a/xen/include/asm-x86/config.h	Tue Jul 13 09:04:27 2004 +0000
    11.2 +++ b/xen/include/asm-x86/config.h	Wed Jul 14 07:47:43 2004 +0000
    11.3 @@ -11,6 +11,7 @@
    11.4  
    11.5  #define CONFIG_SMP 1
    11.6  #define CONFIG_X86_LOCAL_APIC 1
    11.7 +#define CONFIG_X86_GOOD_APIC 1
    11.8  #define CONFIG_X86_IO_APIC 1
    11.9  #define CONFIG_X86_L1_CACHE_SHIFT 5
   11.10  
    12.1 --- a/xen/include/asm-x86/mm.h	Tue Jul 13 09:04:27 2004 +0000
    12.2 +++ b/xen/include/asm-x86/mm.h	Wed Jul 14 07:47:43 2004 +0000
    12.3 @@ -277,6 +277,12 @@ static inline int get_page_and_type(stru
    12.4  int check_descriptor(unsigned long a, unsigned long b);
    12.5  
    12.6  /*
    12.7 + * Use currently-executing domain's pagetables on the specified CPUs.
    12.8 + * i.e., stop borrowing someone else's tables if you are the idle domain.
    12.9 + */
   12.10 +void synchronise_pagetables(unsigned long cpu_mask);
   12.11 +
   12.12 +/*
   12.13   * The MPT (machine->physical mapping table) is an array of word-sized
   12.14   * values, indexed on machine frame number. It is expected that guest OSes
   12.15   * will use it to store a "physical" frame number to give the appearance of