ia64/xen-unstable

changeset 17632:9f8b8315339e

minios: free netfront resources on error/shutdown

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon May 12 10:36:27 2008 +0100 (2008-05-12)
parents a6e2679b1aad
children c6533d246a81
files extras/mini-os/fbfront.c extras/mini-os/include/mm.h extras/mini-os/lib/xmalloc.c extras/mini-os/netfront.c
line diff
     1.1 --- a/extras/mini-os/fbfront.c	Mon May 12 10:16:18 2008 +0100
     1.2 +++ b/extras/mini-os/fbfront.c	Mon May 12 10:36:27 2008 +0100
     1.3 @@ -210,7 +210,7 @@ void shutdown_kbdfront(struct kbdfront_d
     1.4  
     1.5      unbind_evtchn(dev->evtchn);
     1.6  
     1.7 -    free_pages(dev->page,0);
     1.8 +    free_page(dev->page);
     1.9      free(nodename);
    1.10      free(dev->backend);
    1.11      free(dev);
    1.12 @@ -521,7 +521,7 @@ void shutdown_fbfront(struct fbfront_dev
    1.13  
    1.14      unbind_evtchn(dev->evtchn);
    1.15  
    1.16 -    free_pages(dev->page,0);
    1.17 +    free_page(dev->page);
    1.18      free(nodename);
    1.19      free(dev->backend);
    1.20      free(dev);
     2.1 --- a/extras/mini-os/include/mm.h	Mon May 12 10:16:18 2008 +0100
     2.2 +++ b/extras/mini-os/include/mm.h	Mon May 12 10:36:27 2008 +0100
     2.3 @@ -48,6 +48,7 @@ void init_mm(void);
     2.4  unsigned long alloc_pages(int order);
     2.5  #define alloc_page()    alloc_pages(0)
     2.6  void free_pages(void *pointer, int order);
     2.7 +#define free_page(p)    free_pages(p, 0)
     2.8  
     2.9  static __inline__ int get_order(unsigned long size)
    2.10  {
     3.1 --- a/extras/mini-os/lib/xmalloc.c	Mon May 12 10:16:18 2008 +0100
     3.2 +++ b/extras/mini-os/lib/xmalloc.c	Mon May 12 10:36:27 2008 +0100
     3.3 @@ -264,7 +264,7 @@ void xfree(const void *p)
     3.4              printk("Bug\n");
     3.5              *(int*)0=0;
     3.6          }
     3.7 -        free_pages(hdr, 0);
     3.8 +        free_page(hdr);
     3.9      }
    3.10      else
    3.11      {
     4.1 --- a/extras/mini-os/netfront.c	Mon May 12 10:16:18 2008 +0100
     4.2 +++ b/extras/mini-os/netfront.c	Mon May 12 10:36:27 2008 +0100
     4.3 @@ -52,6 +52,7 @@ struct netfront_dev {
     4.4  
     4.5      char *nodename;
     4.6      char *backend;
     4.7 +    char *mac;
     4.8  
     4.9      xenbus_event_queue events;
    4.10  
    4.11 @@ -263,6 +264,39 @@ void netfront_select_handler(evtchn_port
    4.12  }
    4.13  #endif
    4.14  
    4.15 +static void free_netfront(struct netfront_dev *dev)
    4.16 +{
    4.17 +    int i;
    4.18 +
    4.19 +    for(i=0;i<NET_TX_RING_SIZE;i++)
    4.20 +	down(&dev->tx_sem);
    4.21 +
    4.22 +    mask_evtchn(dev->evtchn);
    4.23 +
    4.24 +    free(dev->mac);
    4.25 +    free(dev->backend);
    4.26 +
    4.27 +    gnttab_end_access(dev->rx_ring_ref);
    4.28 +    gnttab_end_access(dev->tx_ring_ref);
    4.29 +
    4.30 +    free_page(dev->rx.sring);
    4.31 +    free_page(dev->tx.sring);
    4.32 +
    4.33 +    unbind_evtchn(dev->evtchn);
    4.34 +
    4.35 +    for(i=0;i<NET_RX_RING_SIZE;i++) {
    4.36 +	gnttab_end_access(dev->rx_buffers[i].gref);
    4.37 +	free_page(dev->rx_buffers[i].page);
    4.38 +    }
    4.39 +
    4.40 +    for(i=0;i<NET_TX_RING_SIZE;i++)
    4.41 +	if (dev->tx_buffers[i].page)
    4.42 +	    free_page(dev->tx_buffers[i].page);
    4.43 +
    4.44 +    free(dev->nodename);
    4.45 +    free(dev);
    4.46 +}
    4.47 +
    4.48  struct netfront_dev *init_netfront(char *nodename, void (*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6], char **ip)
    4.49  {
    4.50      xenbus_transaction_t xbt;
    4.51 @@ -272,7 +306,6 @@ struct netfront_dev *init_netfront(char 
    4.52      struct netif_rx_sring *rxs;
    4.53      int retry=0;
    4.54      int i;
    4.55 -    char* mac;
    4.56      char* msg;
    4.57  
    4.58      struct netfront_dev *dev;
    4.59 @@ -288,6 +321,7 @@ struct netfront_dev *init_netfront(char 
    4.60      printk("************************ NETFRONT for %s **********\n\n\n", nodename);
    4.61  
    4.62      dev = malloc(sizeof(*dev));
    4.63 +    memset(dev, 0, sizeof(*dev));
    4.64      dev->nodename = strdup(nodename);
    4.65  
    4.66      printk("net TX ring size %d\n", NET_TX_RING_SIZE);
    4.67 @@ -314,7 +348,7 @@ struct netfront_dev *init_netfront(char 
    4.68  #endif
    4.69          evtchn_alloc_unbound(dev->dom, netfront_handler, dev, &dev->evtchn);
    4.70  
    4.71 -    txs = (struct netif_tx_sring*) alloc_page();
    4.72 +    txs = (struct netif_tx_sring *) alloc_page();
    4.73      rxs = (struct netif_rx_sring *) alloc_page();
    4.74      memset(txs,0,PAGE_SIZE);
    4.75      memset(rxs,0,PAGE_SIZE);
    4.76 @@ -328,11 +362,12 @@ struct netfront_dev *init_netfront(char 
    4.77      dev->tx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(txs),0);
    4.78      dev->rx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(rxs),0);
    4.79  
    4.80 +    init_rx_buffers(dev);
    4.81 +
    4.82      dev->netif_rx = thenetif_rx;
    4.83  
    4.84      dev->events = NULL;
    4.85  
    4.86 -    // FIXME: proper frees on failures
    4.87  again:
    4.88      err = xenbus_transaction_start(&xbt);
    4.89      if (err) {
    4.90 @@ -379,25 +414,22 @@ again:
    4.91  
    4.92  abort_transaction:
    4.93      xenbus_transaction_end(xbt, 1, &retry);
    4.94 -    return NULL;
    4.95 +    goto error;
    4.96  
    4.97  done:
    4.98  
    4.99      snprintf(path, sizeof(path), "%s/backend", nodename);
   4.100      msg = xenbus_read(XBT_NIL, path, &dev->backend);
   4.101      snprintf(path, sizeof(path), "%s/mac", nodename);
   4.102 -    msg = xenbus_read(XBT_NIL, path, &mac);
   4.103 +    msg = xenbus_read(XBT_NIL, path, &dev->mac);
   4.104  
   4.105 -    if ((dev->backend == NULL) || (mac == NULL)) {
   4.106 -        struct evtchn_close op = { dev->evtchn };
   4.107 +    if ((dev->backend == NULL) || (dev->mac == NULL)) {
   4.108          printk("%s: backend/mac failed\n", __func__);
   4.109 -        unbind_evtchn(dev->evtchn);
   4.110 -        HYPERVISOR_event_channel_op(EVTCHNOP_close, &op);
   4.111 -        return NULL;
   4.112 +        goto error;
   4.113      }
   4.114  
   4.115      printk("backend at %s\n",dev->backend);
   4.116 -    printk("mac is %s\n",mac);
   4.117 +    printk("mac is %s\n",dev->mac);
   4.118  
   4.119      {
   4.120          char path[strlen(dev->backend) + 1 + 5 + 1];
   4.121 @@ -415,13 +447,12 @@ done:
   4.122  
   4.123      printk("**************************\n");
   4.124  
   4.125 -    init_rx_buffers(dev);
   4.126      unmask_evtchn(dev->evtchn);
   4.127  
   4.128          /* Special conversion specifier 'hh' needed for __ia64__. Without
   4.129             this mini-os panics with 'Unaligned reference'. */
   4.130      if (rawmac)
   4.131 -	sscanf(mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
   4.132 +	sscanf(dev->mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
   4.133              &rawmac[0],
   4.134              &rawmac[1],
   4.135              &rawmac[2],
   4.136 @@ -430,6 +461,9 @@ done:
   4.137              &rawmac[5]);
   4.138  
   4.139      return dev;
   4.140 +error:
   4.141 +    free_netfront(dev);
   4.142 +    return NULL;
   4.143  }
   4.144  
   4.145  #ifdef HAVE_LIBC
   4.146 @@ -467,11 +501,7 @@ void shutdown_netfront(struct netfront_d
   4.147  
   4.148      xenbus_unwatch_path(XBT_NIL, path);
   4.149  
   4.150 -    unbind_evtchn(dev->evtchn);
   4.151 -
   4.152 -    free(nodename);
   4.153 -    free(dev->backend);
   4.154 -    free(dev);
   4.155 +    free_netfront(dev);
   4.156  }
   4.157  
   4.158