ia64/xen-unstable

changeset 3466:9e77c2678efa

bitkeeper revision 1.1159.1.534 (41ee6a97zcf6EN9RIf_rbRQA07sS8Q)

Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
author smh22@tempest.cl.cam.ac.uk
date Wed Jan 19 14:11:35 2005 +0000 (2005-01-19)
parents cee684f223ee 023c30e91254
children 12e84ce22ce3
files linux-2.4.28-xen-sparse/arch/xen/mm/init.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.h linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_datapath.c linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_userdev.c linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c xen/arch/x86/e820.c xen/common/dom0_ops.c xen/common/page_alloc.c xen/include/xen/mm.h
line diff
     1.1 --- a/linux-2.4.28-xen-sparse/arch/xen/mm/init.c	Tue Jan 18 08:28:11 2005 +0000
     1.2 +++ b/linux-2.4.28-xen-sparse/arch/xen/mm/init.c	Wed Jan 19 14:11:35 2005 +0000
     1.3 @@ -377,7 +377,7 @@ static int __init free_pages_init(void)
     1.4      }
     1.5  #ifdef CONFIG_HIGHMEM
     1.6      for (pfn = highend_pfn-1; pfn >= highstart_pfn; pfn--)
     1.7 -        one_highpage_init((struct page *) (mem_map + pfn), pfn,
     1.8 +        one_highpage_init((struct page *) (mem_map + pfn),
     1.9                            (pfn < xen_start_info.nr_pages));
    1.10      totalram_pages += totalhigh_pages;
    1.11  #endif
     2.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.c	Tue Jan 18 08:28:11 2005 +0000
     2.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.c	Wed Jan 19 14:11:35 2005 +0000
     2.3 @@ -41,9 +41,9 @@ int __init xlblk_init(void)
     2.4      DPRINTK("   tap - Frontend connection init:\n");
     2.5      
     2.6      active_reqs_init();
     2.7 +    blkif_interface_init();
     2.8 +    blkdev_schedule_init();
     2.9      
    2.10 -    ptfe_blkif.status = DISCONNECTED;
    2.11 -
    2.12      (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
    2.13                                      CALLBACK_IN_BLOCKING_CONTEXT);
    2.14  
     3.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.h	Tue Jan 18 08:28:11 2005 +0000
     3.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap.h	Wed Jan 19 14:11:35 2005 +0000
     3.3 @@ -23,23 +23,32 @@
     3.4  #include <asm/pgalloc.h>
     3.5  #include <asm-xen/hypervisor.h>
     3.6  #include <asm-xen/xen-public/io/blkif.h>
     3.7 +#include <asm-xen/xen-public/io/ring.h>
     3.8 +
     3.9 +/* Used to signal to the backend that this is a tap domain. */
    3.10 +#define BLKTAP_COOKIE 0xbeadfeed
    3.11  
    3.12  /* -------[ debug / pretty printing ]--------------------------------- */
    3.13  
    3.14  #if 0
    3.15 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
    3.16 +                           __FILE__ , __LINE__ , ## _a )
    3.17 +#else
    3.18 +#define DPRINTK(_f, _a...) ((void)0)
    3.19 +#endif
    3.20 +
    3.21 +#if 1
    3.22  #define ASSERT(_p) \
    3.23      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
    3.24      __LINE__, __FILE__); *(int*)0=0; }
    3.25 -#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
    3.26 -                           __FILE__ , __LINE__ , ## _a )
    3.27  #else
    3.28  #define ASSERT(_p) ((void)0)
    3.29 -#define DPRINTK(_f, _a...) ((void)0)
    3.30  #endif
    3.31  
    3.32  #define WPRINTK(fmt, args...) printk(KERN_WARNING "blk_tap: " fmt, ##args)
    3.33  
    3.34 -/* -------[ connection / request tracking ]--------------------------- */
    3.35 +
    3.36 +/* -------[ connection tracking ]------------------------------------- */
    3.37  
    3.38  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
    3.39  #define VMALLOC_VMADDR(x) ((unsigned long)(x))
    3.40 @@ -49,30 +58,40 @@ extern spinlock_t blkif_io_lock;
    3.41  
    3.42  typedef struct blkif_st {
    3.43      /* Unique identifier for this interface. */
    3.44 -    domid_t          domid;
    3.45 -    unsigned int     handle;
    3.46 +    domid_t             domid;
    3.47 +    unsigned int        handle;
    3.48      /* Physical parameters of the comms window. */
    3.49 -    unsigned long    shmem_frame;
    3.50 -    unsigned int     evtchn;
    3.51 -    int              irq;
    3.52 +    unsigned long       shmem_frame;
    3.53 +    unsigned int        evtchn;
    3.54 +    int                 irq;
    3.55      /* Comms information. */
    3.56 -    blkif_ring_t    *blk_ring_base; /* ioremap()'ed ptr to shmem_frame. */
    3.57 -    BLKIF_RING_IDX     blk_req_cons;  /* Request consumer. */
    3.58 -    BLKIF_RING_IDX     blk_resp_prod; /* Private version of resp. producer. */
    3.59 +    blkif_back_ring_t   blk_ring;
    3.60      
    3.61      enum { DISCONNECTED, DISCONNECTING, CONNECTED } status;
    3.62      /*
    3.63       * DISCONNECT response is deferred until pending requests are ack'ed.
    3.64       * We therefore need to store the id from the original request.
    3.65 -     */    u8               disconnect_rspid;
    3.66 -    struct blkif_st *hash_next;
    3.67 -    struct list_head blkdev_list;
    3.68 -    spinlock_t       blk_ring_lock;
    3.69 -    atomic_t         refcnt;
    3.70 -    
    3.71 +     */    
    3.72 +    u8                  disconnect_rspid;
    3.73 +    struct blkif_st    *hash_next;
    3.74 +    struct list_head    blkdev_list;
    3.75 +    spinlock_t          blk_ring_lock;
    3.76 +    atomic_t            refcnt;
    3.77      struct work_struct work;
    3.78  } blkif_t;
    3.79  
    3.80 +blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle);
    3.81 +void blkif_disconnect_complete(blkif_t *blkif);
    3.82 +#define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
    3.83 +#define blkif_put(_b)                             \
    3.84 +    do {                                          \
    3.85 +        if ( atomic_dec_and_test(&(_b)->refcnt) ) \
    3.86 +            blkif_disconnect_complete(_b);        \
    3.87 +    } while (0)
    3.88 +
    3.89 +
    3.90 +/* -------[ active request tracking ]--------------------------------- */
    3.91 +
    3.92  typedef struct {
    3.93      blkif_t       *blkif;
    3.94      unsigned long  id;
    3.95 @@ -80,48 +99,16 @@ typedef struct {
    3.96      unsigned long  mach_fas[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    3.97      unsigned long  virt_fas[BLKIF_MAX_SEGMENTS_PER_REQUEST];
    3.98      int            next_free;
    3.99 +    int inuse; /* debugging */
   3.100  } active_req_t;
   3.101  
   3.102 -
   3.103 -/* -------[ block ring structs ]-------------------------------------- */
   3.104 -
   3.105 -/* Types of ring. */
   3.106 -#define BLKIF_REQ_RING_TYPE 1
   3.107 -#define BLKIF_RSP_RING_TYPE 2
   3.108 -
   3.109 -/* generic ring struct. */
   3.110 -typedef struct blkif_generic_ring_struct {
   3.111 -    int type;
   3.112 -} blkif_generic_ring_t;
   3.113 -
   3.114 -/* A requestor's view of a ring. */
   3.115 -typedef struct blkif_req_ring_struct {
   3.116 -
   3.117 -    int type;                    /* Will be BLKIF_REQ_RING_TYPE        */
   3.118 -    BLKIF_RING_IDX req_prod;     /* PRIVATE req_prod index             */
   3.119 -    BLKIF_RING_IDX rsp_cons;     /* Response consumer index            */
   3.120 -    blkif_ring_t *ring;          /* Pointer to shared ring struct      */
   3.121 +typedef unsigned int ACTIVE_RING_IDX;
   3.122  
   3.123 -} blkif_req_ring_t;
   3.124 -
   3.125 -#define BLKIF_REQ_RING_INIT { BLKIF_REQ_RING_TYPE, 0, 0, 0 }
   3.126 -
   3.127 -/* A responder's view of a ring. */
   3.128 -typedef struct blkif_rsp_ring_struct {
   3.129 +active_req_t *lookup_active_req(ACTIVE_RING_IDX idx);
   3.130 +inline unsigned int ID_TO_IDX(unsigned long id);
   3.131 +inline domid_t ID_TO_DOM(unsigned long id);
   3.132  
   3.133 -    int type;       
   3.134 -    BLKIF_RING_IDX rsp_prod;     /* PRIVATE rsp_prod index             */
   3.135 -    BLKIF_RING_IDX req_cons;     /* Request consumer index             */
   3.136 -    blkif_ring_t *ring;          /* Pointer to shared ring struct      */
   3.137 -
   3.138 -} blkif_rsp_ring_t;
   3.139 -
   3.140 -#define BLKIF_RSP_RING_INIT = { BLKIF_RSP_RING_TYPE, 0, 0, 0 }
   3.141 -
   3.142 -#define RING(a) (blkif_generic_ring_t *)(a)
   3.143 -
   3.144 -inline int BLKTAP_RING_FULL(blkif_generic_ring_t *ring);
   3.145 -
   3.146 +inline void active_reqs_init(void);
   3.147  
   3.148  /* -------[ interposition -> character device interface ]------------- */
   3.149  
   3.150 @@ -135,6 +122,7 @@ inline int BLKTAP_RING_FULL(blkif_generi
   3.151  #define BLKTAP_IOCTL_KICK_FE         1
   3.152  #define BLKTAP_IOCTL_KICK_BE         2
   3.153  #define BLKTAP_IOCTL_SETMODE         3
   3.154 +#define BLKTAP_IOCTL_PRINT_IDXS      100  
   3.155  
   3.156  /* blktap switching modes: (Set with BLKTAP_IOCTL_SETMODE)             */
   3.157  #define BLKTAP_MODE_PASSTHROUGH      0x00000000  /* default            */
   3.158 @@ -196,22 +184,12 @@ extern unsigned long mmap_vstart;
   3.159  #define RING_PAGES 128 
   3.160  extern unsigned long rings_vstart;
   3.161  
   3.162 +
   3.163  /* -------[ Here be globals ]----------------------------------------- */
   3.164 -
   3.165  extern unsigned long blktap_mode;
   3.166  
   3.167 -
   3.168 -/* blkif struct, containing ring to FE domain */
   3.169 -extern blkif_t ptfe_blkif; 
   3.170 -
   3.171  /* Connection to a single backend domain. */
   3.172 -extern blkif_ring_t *blk_ptbe_ring;   /* Ring from the PT to the BE dom    */ 
   3.173 -extern BLKIF_RING_IDX ptbe_resp_cons; /* Response consumer for comms ring. */
   3.174 -extern BLKIF_RING_IDX ptbe_req_prod;  /* Private request producer.         */
   3.175 -
   3.176 -/* Rings up to user space. */ 
   3.177 -extern blkif_req_ring_t fe_ring;// = BLKIF_REQ_RING_INIT;
   3.178 -extern blkif_rsp_ring_t be_ring;// = BLKIF_RSP_RING_INIT;
   3.179 +extern blkif_front_ring_t blktap_be_ring;
   3.180  
   3.181  /* Event channel to backend domain. */
   3.182  extern unsigned int blkif_ptbe_evtchn;
   3.183 @@ -224,10 +202,13 @@ extern unsigned long blktap_ring_ok;
   3.184  /* init function for character device interface.                       */
   3.185  int blktap_init(void);
   3.186  
   3.187 +/* init function for the blkif cache. */
   3.188 +void __init blkif_interface_init(void);
   3.189 +void __init blkdev_schedule_init(void);
   3.190 +void blkif_deschedule(blkif_t *blkif);
   3.191 +
   3.192  /* interfaces to the char driver, passing messages to and from apps.   */
   3.193  void blktap_kick_user(void);
   3.194 -int blktap_write_to_ring(blkif_request_t *req);
   3.195 -
   3.196  
   3.197  /* user ring access functions: */
   3.198  int blktap_write_fe_ring(blkif_request_t *req);
   3.199 @@ -235,11 +216,12 @@ int blktap_write_be_ring(blkif_response_
   3.200  int blktap_read_fe_ring(void);
   3.201  int blktap_read_be_ring(void);
   3.202  
   3.203 -/* and the helpers they call: */
   3.204 -inline int write_resp_to_fe_ring(blkif_response_t *rsp);
   3.205 -inline void kick_fe_domain(void);
   3.206 +/* fe/be ring access functions: */
   3.207 +int write_resp_to_fe_ring(blkif_t *blkif, blkif_response_t *rsp);
   3.208 +int write_req_to_be_ring(blkif_request_t *req);
   3.209  
   3.210 -inline int write_req_to_be_ring(blkif_request_t *req);
   3.211 +/* event notification functions */
   3.212 +inline void kick_fe_domain(blkif_t *blkif);
   3.213  inline void kick_be_domain(void);
   3.214  
   3.215  /* Interrupt handlers. */
   3.216 @@ -250,5 +232,8 @@ irqreturn_t blkif_ptfe_int(int irq, void
   3.217  /* Control message receiver. */
   3.218  extern void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id);
   3.219  
   3.220 +/* debug */
   3.221 +void print_vm_ring_idxs(void);
   3.222 +        
   3.223  #define __BLKINT_H__
   3.224  #endif
     4.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c	Tue Jan 18 08:28:11 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_controlmsg.c	Wed Jan 19 14:11:35 2005 +0000
     4.3 @@ -32,10 +32,71 @@ unsigned int blkif_ptbe_evtchn;
     4.4  
     4.5  /*-----[ Control Messages to/from Frontend VMs ]--------------------------*/
     4.6  
     4.7 +#define BLKIF_HASHSZ 1024
     4.8 +#define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1))
     4.9 +
    4.10 +static kmem_cache_t *blkif_cachep;
    4.11 +static blkif_t      *blkif_hash[BLKIF_HASHSZ];
    4.12 +
    4.13 +blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle)
    4.14 +{
    4.15 +    blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)];
    4.16 +    while ( (blkif != NULL) && 
    4.17 +            ((blkif->domid != domid) || (blkif->handle != handle)) )
    4.18 +        blkif = blkif->hash_next;
    4.19 +    return blkif;
    4.20 +}
    4.21 +
    4.22 +static void __blkif_disconnect_complete(void *arg)
    4.23 +{
    4.24 +    blkif_t              *blkif = (blkif_t *)arg;
    4.25 +    ctrl_msg_t            cmsg;
    4.26 +    blkif_be_disconnect_t disc;
    4.27 +
    4.28 +    /*
    4.29 +     * These can't be done in blkif_disconnect() because at that point there
    4.30 +     * may be outstanding requests at the disc whose asynchronous responses
    4.31 +     * must still be notified to the remote driver.
    4.32 +     */
    4.33 +    unbind_evtchn_from_irq(blkif->evtchn);
    4.34 +    vfree(blkif->blk_ring.sring);
    4.35 +
    4.36 +    /* Construct the deferred response message. */
    4.37 +    cmsg.type         = CMSG_BLKIF_BE;
    4.38 +    cmsg.subtype      = CMSG_BLKIF_BE_DISCONNECT;
    4.39 +    cmsg.id           = blkif->disconnect_rspid;
    4.40 +    cmsg.length       = sizeof(blkif_be_disconnect_t);
    4.41 +    disc.domid        = blkif->domid;
    4.42 +    disc.blkif_handle = blkif->handle;
    4.43 +    disc.status       = BLKIF_BE_STATUS_OKAY;
    4.44 +    memcpy(cmsg.msg, &disc, sizeof(disc));
    4.45 +
    4.46 +    /*
    4.47 +     * Make sure message is constructed /before/ status change, because
    4.48 +     * after the status change the 'blkif' structure could be deallocated at
    4.49 +     * any time. Also make sure we send the response /after/ status change,
    4.50 +     * as otherwise a subsequent CONNECT request could spuriously fail if
    4.51 +     * another CPU doesn't see the status change yet.
    4.52 +     */
    4.53 +    mb();
    4.54 +    if ( blkif->status != DISCONNECTING )
    4.55 +        BUG();
    4.56 +    blkif->status = DISCONNECTED;
    4.57 +    mb();
    4.58 +
    4.59 +    /* Send the successful response. */
    4.60 +    ctrl_if_send_response(&cmsg);
    4.61 +}
    4.62 +
    4.63 +void blkif_disconnect_complete(blkif_t *blkif)
    4.64 +{
    4.65 +    INIT_WORK(&blkif->work, __blkif_disconnect_complete, (void *)blkif);
    4.66 +    schedule_work(&blkif->work);
    4.67 +}
    4.68  
    4.69  void blkif_ptfe_create(blkif_be_create_t *create)
    4.70  {
    4.71 -    blkif_t      *blkif;
    4.72 +    blkif_t      *blkif, **pblkif;
    4.73      domid_t       domid  = create->domid;
    4.74      unsigned int  handle = create->blkif_handle;
    4.75  
    4.76 @@ -43,16 +104,38 @@ void blkif_ptfe_create(blkif_be_create_t
    4.77      /* May want to store info on the connecting domain here. */
    4.78  
    4.79      DPRINTK("PT got BE_CREATE\n");
    4.80 -    blkif = &ptfe_blkif; /* for convenience if the hash is readded later. */
    4.81 +
    4.82 +    if ( (blkif = kmem_cache_alloc(blkif_cachep, GFP_KERNEL)) == NULL )
    4.83 +    {
    4.84 +        DPRINTK("Could not create blkif: out of memory\n");
    4.85 +        create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    4.86 +        return;
    4.87 +    }
    4.88  
    4.89      /* blkif struct init code from blkback.c */
    4.90      memset(blkif, 0, sizeof(*blkif));
    4.91      blkif->domid  = domid;
    4.92      blkif->handle = handle;
    4.93 -    blkif->status = DISCONNECTED;    
    4.94 +    blkif->status = DISCONNECTED;  
    4.95      spin_lock_init(&blkif->blk_ring_lock);
    4.96      atomic_set(&blkif->refcnt, 0);
    4.97  
    4.98 +    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
    4.99 +    while ( *pblkif != NULL )
   4.100 +    {
   4.101 +        if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) )
   4.102 +        {
   4.103 +            DPRINTK("Could not create blkif: already exists\n");
   4.104 +            create->status = BLKIF_BE_STATUS_INTERFACE_EXISTS;
   4.105 +            kmem_cache_free(blkif_cachep, blkif);
   4.106 +            return;
   4.107 +        }
   4.108 +        pblkif = &(*pblkif)->hash_next;
   4.109 +    }
   4.110 +
   4.111 +    blkif->hash_next = *pblkif;
   4.112 +    *pblkif = blkif;
   4.113 +
   4.114      create->status = BLKIF_BE_STATUS_OKAY;
   4.115  }
   4.116  
   4.117 @@ -61,24 +144,59 @@ void blkif_ptfe_destroy(blkif_be_destroy
   4.118  {
   4.119      /* Clear anything that we initialized above. */
   4.120  
   4.121 +    domid_t       domid  = destroy->domid;
   4.122 +    unsigned int  handle = destroy->blkif_handle;
   4.123 +    blkif_t     **pblkif, *blkif;
   4.124 +
   4.125      DPRINTK("PT got BE_DESTROY\n");
   4.126 +    
   4.127 +    pblkif = &blkif_hash[BLKIF_HASH(domid, handle)];
   4.128 +    while ( (blkif = *pblkif) != NULL )
   4.129 +    {
   4.130 +        if ( (blkif->domid == domid) && (blkif->handle == handle) )
   4.131 +        {
   4.132 +            if ( blkif->status != DISCONNECTED )
   4.133 +                goto still_connected;
   4.134 +            goto destroy;
   4.135 +        }
   4.136 +        pblkif = &blkif->hash_next;
   4.137 +    }
   4.138 +
   4.139 +    destroy->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   4.140 +    return;
   4.141 +
   4.142 + still_connected:
   4.143 +    destroy->status = BLKIF_BE_STATUS_INTERFACE_CONNECTED;
   4.144 +    return;
   4.145 +
   4.146 + destroy:
   4.147 +    *pblkif = blkif->hash_next;
   4.148 +    kmem_cache_free(blkif_cachep, blkif);
   4.149      destroy->status = BLKIF_BE_STATUS_OKAY;
   4.150  }
   4.151  
   4.152  void blkif_ptfe_connect(blkif_be_connect_t *connect)
   4.153  {
   4.154 -    domid_t       domid  = connect->domid;
   4.155 -    /*unsigned int  handle = connect->blkif_handle;*/
   4.156 -    unsigned int  evtchn = connect->evtchn;
   4.157 -    unsigned long shmem_frame = connect->shmem_frame;
   4.158 +    domid_t        domid  = connect->domid;
   4.159 +    unsigned int   handle = connect->blkif_handle;
   4.160 +    unsigned int   evtchn = connect->evtchn;
   4.161 +    unsigned long  shmem_frame = connect->shmem_frame;
   4.162      struct vm_struct *vma;
   4.163 -    pgprot_t      prot;
   4.164 -    int           error;
   4.165 -    blkif_t      *blkif;
   4.166 +    pgprot_t       prot;
   4.167 +    int            error;
   4.168 +    blkif_t       *blkif;
   4.169 +    blkif_sring_t *sring;
   4.170  
   4.171      DPRINTK("PT got BE_CONNECT\n");
   4.172  
   4.173 -    blkif = &ptfe_blkif; /* for convenience if the hash is readded later. */
   4.174 +    blkif = blkif_find_by_handle(domid, handle);
   4.175 +    if ( unlikely(blkif == NULL) )
   4.176 +    {
   4.177 +        DPRINTK("blkif_connect attempted for non-existent blkif (%u,%u)\n", 
   4.178 +                connect->domid, connect->blkif_handle); 
   4.179 +        connect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   4.180 +        return;
   4.181 +    }
   4.182  
   4.183      if ( (vma = get_vm_area(PAGE_SIZE, VM_IOREMAP)) == NULL )
   4.184      {
   4.185 @@ -112,30 +230,51 @@ void blkif_ptfe_connect(blkif_be_connect
   4.186          return;
   4.187      }
   4.188  
   4.189 +    sring = (blkif_sring_t *)vma->addr;
   4.190 +    SHARED_RING_INIT(BLKIF_RING, sring);
   4.191 +    BACK_RING_INIT(BLKIF_RING, &blkif->blk_ring, sring);
   4.192 +    
   4.193      blkif->evtchn        = evtchn;
   4.194      blkif->irq           = bind_evtchn_to_irq(evtchn);
   4.195      blkif->shmem_frame   = shmem_frame;
   4.196 -    blkif->blk_ring_base = (blkif_ring_t *)vma->addr;
   4.197      blkif->status        = CONNECTED;
   4.198 -    /*blkif_get(blkif);*/
   4.199 +    blkif_get(blkif);
   4.200  
   4.201      request_irq(blkif->irq, blkif_ptfe_int, 0, "blkif-pt-backend", blkif);
   4.202  
   4.203      connect->status = BLKIF_BE_STATUS_OKAY;
   4.204  }
   4.205  
   4.206 -void blkif_ptfe_disconnect(blkif_be_disconnect_t *disconnect)
   4.207 +int blkif_ptfe_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id)
   4.208  {
   4.209 -    /*
   4.210 -     * don't actually set the passthrough to disconnected.
   4.211 -     * We just act as a pipe, and defer to the real ends to handle things like
   4.212 -     * recovery.
   4.213 -     */
   4.214 +    domid_t       domid  = disconnect->domid;
   4.215 +    unsigned int  handle = disconnect->blkif_handle;
   4.216 +    blkif_t      *blkif;
   4.217  
   4.218      DPRINTK("PT got BE_DISCONNECT\n");
   4.219 +    
   4.220 +    blkif = blkif_find_by_handle(domid, handle);
   4.221 +    if ( unlikely(blkif == NULL) )
   4.222 +    {
   4.223 +        DPRINTK("blkif_disconnect attempted for non-existent blkif"
   4.224 +                " (%u,%u)\n", disconnect->domid, disconnect->blkif_handle); 
   4.225 +        disconnect->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
   4.226 +        return 1; /* Caller will send response error message. */
   4.227 +    }
   4.228 +
   4.229 +    if ( blkif->status == CONNECTED )
   4.230 +    {
   4.231 +        blkif->status = DISCONNECTING;
   4.232 +        blkif->disconnect_rspid = rsp_id;
   4.233 +        wmb(); /* Let other CPUs see the status change. */
   4.234 +        free_irq(blkif->irq, blkif);
   4.235 +        blkif_deschedule(blkif);
   4.236 +        blkif_put(blkif);
   4.237 +        return 0; /* Caller should not send response message. */
   4.238 +    }
   4.239  
   4.240      disconnect->status = BLKIF_BE_STATUS_OKAY;
   4.241 -    return;
   4.242 +    return 1;
   4.243  }
   4.244  
   4.245  /*-----[ Control Messages to/from Backend VM ]----------------------------*/
   4.246 @@ -150,7 +289,7 @@ static void blkif_ptbe_send_interface_co
   4.247      };
   4.248      blkif_fe_interface_connect_t *msg = (void*)cmsg.msg;
   4.249      msg->handle      = 0;
   4.250 -    msg->shmem_frame = virt_to_machine(blk_ptbe_ring) >> PAGE_SHIFT;
   4.251 +    msg->shmem_frame = virt_to_machine(blktap_be_ring.sring) >> PAGE_SHIFT;
   4.252      
   4.253      ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
   4.254  }
   4.255 @@ -162,9 +301,11 @@ static void blkif_ptbe_close(void)
   4.256  /* Move from CLOSED to DISCONNECTED state. */
   4.257  static void blkif_ptbe_disconnect(void)
   4.258  {
   4.259 -    blk_ptbe_ring = (blkif_ring_t *)__get_free_page(GFP_KERNEL);
   4.260 -    blk_ptbe_ring->req_prod = blk_ptbe_ring->resp_prod 
   4.261 -                            = ptbe_resp_cons = ptbe_req_prod = 0;
   4.262 +    blkif_sring_t *sring;
   4.263 +    
   4.264 +    sring = (blkif_sring_t *)__get_free_page(GFP_KERNEL);
   4.265 +    SHARED_RING_INIT(BLKIF_RING, sring);
   4.266 +    FRONT_RING_INIT(BLKIF_RING, &blktap_be_ring, sring);
   4.267      blkif_pt_state  = BLKIF_STATE_DISCONNECTED;
   4.268      DPRINTK("Blkif-Passthrough-BE is now DISCONNECTED.\n");
   4.269      blkif_ptbe_send_interface_connect();
   4.270 @@ -319,7 +460,9 @@ void blkif_ctrlif_rx(ctrl_msg_t *msg, un
   4.271          case CMSG_BLKIF_BE_DISCONNECT:
   4.272              if ( msg->length != sizeof(blkif_be_disconnect_t) )
   4.273                  goto parse_error;
   4.274 -            blkif_ptfe_disconnect((blkif_be_disconnect_t *)&msg->msg[0]);
   4.275 +            if ( !blkif_ptfe_disconnect((blkif_be_disconnect_t *)&msg->msg[0],
   4.276 +                    msg->id) )
   4.277 +                return;
   4.278              break;        
   4.279  
   4.280          /* We just ignore anything to do with vbds for now. */
   4.281 @@ -356,3 +499,12 @@ void blkif_ctrlif_rx(ctrl_msg_t *msg, un
   4.282      msg->length = 0;
   4.283      ctrl_if_send_response(msg);
   4.284  }
   4.285 +
   4.286 +/*-----[ All control messages enter here: ]-------------------------------*/
   4.287 +
   4.288 +void __init blkif_interface_init(void)
   4.289 +{
   4.290 +    blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
   4.291 +                                     0, 0, NULL, NULL);
   4.292 +    memset(blkif_hash, 0, sizeof(blkif_hash));
   4.293 +}
     5.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_datapath.c	Tue Jan 18 08:28:11 2005 +0000
     5.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_datapath.c	Wed Jan 19 14:11:35 2005 +0000
     5.3 @@ -5,55 +5,46 @@
     5.4   * Block request routing data path.
     5.5   * 
     5.6   * Copyright (c) 2004, Andrew Warfield
     5.7 - *
     5.8 + * -- see full header in blktap.c
     5.9   */
    5.10   
    5.11  #include "blktap.h"
    5.12 +#include <asm-xen/evtchn.h>
    5.13  
    5.14  /*-----[ The data paths ]-------------------------------------------------*/
    5.15 - 
    5.16 -/* Connections to the frontend domains.*/
    5.17 -blkif_t   ptfe_blkif; 
    5.18 - 
    5.19 +
    5.20  /* Connection to a single backend domain. */
    5.21 -blkif_ring_t *blk_ptbe_ring;   /* Ring from the PT to the BE dom    */ 
    5.22 -BLKIF_RING_IDX ptbe_resp_cons; /* Response consumer for comms ring. */
    5.23 -BLKIF_RING_IDX ptbe_req_prod;  /* Private request producer.         */
    5.24 -
    5.25 -/* Rings up to user space. */ 
    5.26 -blkif_req_ring_t fe_ring;// = BLKIF_REQ_RING_INIT;
    5.27 -blkif_rsp_ring_t be_ring;// = BLKIF_RSP_RING_INIT;
    5.28 -
    5.29 -/*-----[ Ring helpers ]---------------------------------------------------*/
    5.30 -
    5.31 -inline int BLKTAP_RING_FULL(blkif_generic_ring_t *ring)
    5.32 -{
    5.33 -    if (ring->type == BLKIF_REQ_RING_TYPE) {
    5.34 -        blkif_req_ring_t *r = (blkif_req_ring_t *)ring;
    5.35 -        return ( ( r->req_prod - r->rsp_cons ) == BLKIF_RING_SIZE );
    5.36 -    }
    5.37 -    
    5.38 -    /* for now assume that there is always room in the response path. */
    5.39 -    return 0;
    5.40 -}
    5.41 +blkif_front_ring_t blktap_be_ring;
    5.42  
    5.43  /*-----[ Tracking active requests ]---------------------------------------*/
    5.44  
    5.45  /* this must be the same as MAX_PENDING_REQS in blkback.c */
    5.46 -#define MAX_ACTIVE_REQS 64
    5.47 +#define MAX_ACTIVE_REQS ((ACTIVE_RING_IDX)64U)
    5.48  
    5.49 -active_req_t  active_reqs[MAX_ACTIVE_REQS];
    5.50 -unsigned char active_req_ring[MAX_ACTIVE_REQS];
    5.51 -spinlock_t    active_req_lock = SPIN_LOCK_UNLOCKED;
    5.52 -typedef unsigned int ACTIVE_RING_IDX;
    5.53 -ACTIVE_RING_IDX active_prod, active_cons;
    5.54 +active_req_t     active_reqs[MAX_ACTIVE_REQS];
    5.55 +ACTIVE_RING_IDX  active_req_ring[MAX_ACTIVE_REQS];
    5.56 +spinlock_t       active_req_lock = SPIN_LOCK_UNLOCKED;
    5.57 +ACTIVE_RING_IDX  active_prod, active_cons;
    5.58  #define MASK_ACTIVE_IDX(_i) ((_i)&(MAX_ACTIVE_REQS-1))
    5.59  #define ACTIVE_IDX(_ar) (_ar - active_reqs)
    5.60 +#define NR_ACTIVE_REQS (MAX_ACTIVE_REQS - active_prod + active_cons)
    5.61  
    5.62  inline active_req_t *get_active_req(void) 
    5.63  {
    5.64 -    ASSERT(active_cons != active_prod);    
    5.65 -    return &active_reqs[MASK_ACTIVE_IDX(active_cons++)];
    5.66 +    ACTIVE_RING_IDX idx;
    5.67 +    active_req_t *ar;
    5.68 +    unsigned long flags;
    5.69 +        
    5.70 +    ASSERT(active_cons != active_prod);   
    5.71 +    
    5.72 +    spin_lock_irqsave(&active_req_lock, flags);
    5.73 +    idx =  active_req_ring[MASK_ACTIVE_IDX(active_cons++)];
    5.74 +    ar = &active_reqs[idx];
    5.75 +if (ar->inuse) WPRINTK("AR INUSE! (%lu)\n", ar->id);
    5.76 +ar->inuse = 1;
    5.77 +    spin_unlock_irqrestore(&active_req_lock, flags);
    5.78 +    
    5.79 +    return ar;
    5.80  }
    5.81  
    5.82  inline void free_active_req(active_req_t *ar) 
    5.83 @@ -61,10 +52,16 @@ inline void free_active_req(active_req_t
    5.84      unsigned long flags;
    5.85          
    5.86      spin_lock_irqsave(&active_req_lock, flags);
    5.87 +ar->inuse = 0;
    5.88      active_req_ring[MASK_ACTIVE_IDX(active_prod++)] = ACTIVE_IDX(ar);
    5.89      spin_unlock_irqrestore(&active_req_lock, flags);
    5.90  }
    5.91  
    5.92 +active_req_t *lookup_active_req(ACTIVE_RING_IDX idx)
    5.93 +{
    5.94 +    return &active_reqs[idx];   
    5.95 +}
    5.96 +
    5.97  inline void active_reqs_init(void)
    5.98  {
    5.99      ACTIVE_RING_IDX i;
   5.100 @@ -76,55 +73,256 @@ inline void active_reqs_init(void)
   5.101          active_req_ring[i] = i;
   5.102  }
   5.103  
   5.104 +/* Requests passing through the tap to the backend hijack the id field
   5.105 + * in the request message.  In it we put the AR index _AND_ the fe domid.
   5.106 + * the domid is used by the backend to map the pages properly.
   5.107 + */
   5.108 +
   5.109 +static inline unsigned long MAKE_ID(domid_t fe_dom, ACTIVE_RING_IDX idx)
   5.110 +{
   5.111 +    return ( (fe_dom << 16) | idx );
   5.112 +}
   5.113 +
   5.114 +inline unsigned int ID_TO_IDX(unsigned long id) 
   5.115 +{ 
   5.116 +        return ( id & 0x0000ffff );
   5.117 +}
   5.118 +
   5.119 +inline domid_t ID_TO_DOM(unsigned long id) { return (id >> 16); }
   5.120 +
   5.121 +/*-----[ Ring helpers ]---------------------------------------------------*/
   5.122 +
   5.123 +inline int write_resp_to_fe_ring(blkif_t *blkif, blkif_response_t *rsp)
   5.124 +{
   5.125 +    blkif_response_t *resp_d;
   5.126 +    active_req_t *ar;
   5.127 +    
   5.128 +    /* remap id, and free the active req. blkif lookup goes here too.*/
   5.129 +    ar = &active_reqs[ID_TO_IDX(rsp->id)];
   5.130 +    /* WPRINTK("%3u > %3lu\n", ID_TO_IDX(rsp->id), ar->id); */
   5.131 +    rsp->id = ar->id;
   5.132 +    free_active_req(ar);
   5.133 +            
   5.134 +    resp_d = RING_GET_RESPONSE(BLKIF_RING, &blkif->blk_ring,
   5.135 +            blkif->blk_ring.rsp_prod_pvt);
   5.136 +    memcpy(resp_d, rsp, sizeof(blkif_response_t));
   5.137 +    wmb();
   5.138 +    blkif->blk_ring.rsp_prod_pvt++;
   5.139 +            
   5.140 +    return 0;
   5.141 +}
   5.142 +
   5.143 +inline int write_req_to_be_ring(blkif_request_t *req)
   5.144 +{
   5.145 +    blkif_request_t *req_d;
   5.146 +
   5.147 +    req_d = RING_GET_REQUEST(BLKIF_RING, &blktap_be_ring,
   5.148 +            blktap_be_ring.req_prod_pvt);
   5.149 +    memcpy(req_d, req, sizeof(blkif_request_t));
   5.150 +    wmb();
   5.151 +    blktap_be_ring.req_prod_pvt++;
   5.152 +            
   5.153 +    return 0;
   5.154 +}
   5.155 +
   5.156 +inline void kick_fe_domain(blkif_t *blkif) 
   5.157 +{
   5.158 +    RING_PUSH_RESPONSES(BLKIF_RING, &blkif->blk_ring);
   5.159 +    notify_via_evtchn(blkif->evtchn);
   5.160 +    DPRINTK("notified FE(dom %u)\n", blkif->domid);
   5.161 +    
   5.162 +}
   5.163 +
   5.164 +inline void kick_be_domain(void)
   5.165 +{
   5.166 +    wmb(); /* Ensure that the frontend can see the requests. */
   5.167 +    RING_PUSH_REQUESTS(BLKIF_RING, &blktap_be_ring);
   5.168 +    notify_via_evtchn(blkif_ptbe_evtchn);
   5.169 +    DPRINTK("notified BE\n");
   5.170 +}
   5.171 +
   5.172  /*-----[ Data to/from Frontend (client) VMs ]-----------------------------*/
   5.173  
   5.174 +/*-----[ Scheduler list maint -from blkback ]--- */
   5.175 +
   5.176 +static struct list_head blkio_schedule_list;
   5.177 +static spinlock_t blkio_schedule_list_lock;
   5.178 +
   5.179 +static int __on_blkdev_list(blkif_t *blkif)
   5.180 +{
   5.181 +    return blkif->blkdev_list.next != NULL;
   5.182 +}
   5.183 +
   5.184 +static void remove_from_blkdev_list(blkif_t *blkif)
   5.185 +{
   5.186 +    unsigned long flags;
   5.187 +    if ( !__on_blkdev_list(blkif) ) return;
   5.188 +    spin_lock_irqsave(&blkio_schedule_list_lock, flags);
   5.189 +    if ( __on_blkdev_list(blkif) )
   5.190 +    {
   5.191 +        list_del(&blkif->blkdev_list);
   5.192 +        blkif->blkdev_list.next = NULL;
   5.193 +        blkif_put(blkif);
   5.194 +    }
   5.195 +    spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
   5.196 +}
   5.197 +
   5.198 +static void add_to_blkdev_list_tail(blkif_t *blkif)
   5.199 +{
   5.200 +    unsigned long flags;
   5.201 +    if ( __on_blkdev_list(blkif) ) return;
   5.202 +    spin_lock_irqsave(&blkio_schedule_list_lock, flags);
   5.203 +    if ( !__on_blkdev_list(blkif) && (blkif->status == CONNECTED) )
   5.204 +    {
   5.205 +        list_add_tail(&blkif->blkdev_list, &blkio_schedule_list);
   5.206 +        blkif_get(blkif);
   5.207 +    }
   5.208 +    spin_unlock_irqrestore(&blkio_schedule_list_lock, flags);
   5.209 +}
   5.210 +
   5.211 +
   5.212 +/*-----[ Scheduler functions - from blkback ]--- */
   5.213 +
   5.214 +static DECLARE_WAIT_QUEUE_HEAD(blkio_schedule_wait);
   5.215 +
   5.216 +static int do_block_io_op(blkif_t *blkif, int max_to_do);
   5.217 +
   5.218 +static int blkio_schedule(void *arg)
   5.219 +{
   5.220 +    DECLARE_WAITQUEUE(wq, current);
   5.221 +
   5.222 +    blkif_t          *blkif;
   5.223 +    struct list_head *ent;
   5.224 +
   5.225 +    daemonize(
   5.226 +        "xentapd"
   5.227 +        );
   5.228 +
   5.229 +    for ( ; ; )
   5.230 +    {
   5.231 +        /* Wait for work to do. */
   5.232 +        add_wait_queue(&blkio_schedule_wait, &wq);
   5.233 +        set_current_state(TASK_INTERRUPTIBLE);
   5.234 +        if ( (NR_ACTIVE_REQS == MAX_ACTIVE_REQS) || 
   5.235 +             list_empty(&blkio_schedule_list) )
   5.236 +            schedule();
   5.237 +        __set_current_state(TASK_RUNNING);
   5.238 +        remove_wait_queue(&blkio_schedule_wait, &wq);
   5.239 +
   5.240 +        /* Queue up a batch of requests. */
   5.241 +        while ( (NR_ACTIVE_REQS < MAX_ACTIVE_REQS) &&
   5.242 +                !list_empty(&blkio_schedule_list) )
   5.243 +        {
   5.244 +            ent = blkio_schedule_list.next;
   5.245 +            blkif = list_entry(ent, blkif_t, blkdev_list);
   5.246 +            blkif_get(blkif);
   5.247 +            remove_from_blkdev_list(blkif);
   5.248 +            if ( do_block_io_op(blkif, BATCH_PER_DOMAIN) )
   5.249 +                add_to_blkdev_list_tail(blkif);
   5.250 +            blkif_put(blkif);
   5.251 +        }
   5.252 +
   5.253 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
   5.254 +        /* Push the batch through to disc. */
   5.255 +        run_task_queue(&tq_disk);
   5.256 +#endif
   5.257 +    }
   5.258 +}
   5.259 +
   5.260 +static void maybe_trigger_blkio_schedule(void)
   5.261 +{
   5.262 +    /*
   5.263 +     * Needed so that two processes, who together make the following predicate
   5.264 +     * true, don't both read stale values and evaluate the predicate
   5.265 +     * incorrectly. Incredibly unlikely to stall the scheduler on x86, but...
   5.266 +     */
   5.267 +    smp_mb();
   5.268 +
   5.269 +    if ( (NR_ACTIVE_REQS < (MAX_ACTIVE_REQS)) && /* XXX!!! was M_A_R/2*/
   5.270 +         !list_empty(&blkio_schedule_list) ) 
   5.271 +        wake_up(&blkio_schedule_wait);
   5.272 +}
   5.273 +
   5.274 +void blkif_deschedule(blkif_t *blkif)
   5.275 +{
   5.276 +    remove_from_blkdev_list(blkif);
   5.277 +}
   5.278 +
   5.279 +void __init blkdev_schedule_init(void)
   5.280 +{
   5.281 +    spin_lock_init(&blkio_schedule_list_lock);
   5.282 +    INIT_LIST_HEAD(&blkio_schedule_list);
   5.283 +
   5.284 +    if ( kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0 )
   5.285 +        BUG();
   5.286 +}
   5.287 +    
   5.288 +/*-----[ Interrupt entry from a frontend ]------ */
   5.289 +
   5.290  irqreturn_t blkif_ptfe_int(int irq, void *dev_id, struct pt_regs *regs)
   5.291  {
   5.292 +    blkif_t *blkif = dev_id;
   5.293 +
   5.294 +    add_to_blkdev_list_tail(blkif);
   5.295 +    maybe_trigger_blkio_schedule();
   5.296 +    return IRQ_HANDLED;
   5.297 +}
   5.298 +
   5.299 +/*-----[ Other Frontend Ring functions ]-------- */
   5.300 +
   5.301 +/* irqreturn_t blkif_ptfe_int(int irq, void *dev_id, struct pt_regs *regs)*/
   5.302 +static int do_block_io_op(blkif_t *blkif, int max_to_do)
   5.303 +{
   5.304      /* we have pending messages from the real frontend. */
   5.305  
   5.306 -    blkif_request_t *req_s, *req_d;
   5.307 -    BLKIF_RING_IDX fe_rp;
   5.308 +    blkif_request_t *req_s;
   5.309 +    RING_IDX i, rp;
   5.310      unsigned long flags;
   5.311 -    int notify;
   5.312 -    unsigned long i;
   5.313      active_req_t *ar;
   5.314 +    int more_to_do = 0;
   5.315 +    int notify_be = 0, notify_user = 0;
   5.316      
   5.317      DPRINTK("PT got FE interrupt.\n");
   5.318 +
   5.319 +    if (NR_ACTIVE_REQS == MAX_ACTIVE_REQS) return 1;
   5.320      
   5.321      /* lock both rings */
   5.322      spin_lock_irqsave(&blkif_io_lock, flags);
   5.323  
   5.324 -    /* While there are REQUESTS on FERing: */
   5.325 -    fe_rp = ptfe_blkif.blk_ring_base->req_prod;
   5.326 +    rp = blkif->blk_ring.sring->req_prod;
   5.327      rmb();
   5.328 -    notify = (ptfe_blkif.blk_req_cons != fe_rp);
   5.329 -
   5.330 -    for (i = ptfe_blkif.blk_req_cons; i != fe_rp; i++) {
   5.331 -
   5.332 -        /* Get the next request */
   5.333 -        req_s = &ptfe_blkif.blk_ring_base->ring[MASK_BLKIF_IDX(i)].req;
   5.334 +    
   5.335 +    for ( i = blkif->blk_ring.req_cons; 
   5.336 +         (i != rp) && 
   5.337 +            !RING_REQUEST_CONS_OVERFLOW(BLKIF_RING, &blkif->blk_ring, i);
   5.338 +          i++ )
   5.339 +    {
   5.340          
   5.341 +        if ((--max_to_do == 0) || (NR_ACTIVE_REQS == MAX_ACTIVE_REQS)) 
   5.342 +        {
   5.343 +            more_to_do = 1;
   5.344 +            break;
   5.345 +        }
   5.346 +        
   5.347 +        req_s = RING_GET_REQUEST(BLKIF_RING, &blkif->blk_ring, i);
   5.348          /* This is a new request:  
   5.349           * Assign an active request record, and remap the id. 
   5.350           */
   5.351          ar = get_active_req();
   5.352          ar->id = req_s->id;
   5.353 -        req_s->id = ACTIVE_IDX(ar);
   5.354 -        DPRINTK("%3lu < %3lu\n", req_s->id, ar->id);
   5.355 +        ar->blkif = blkif;
   5.356 +        req_s->id = MAKE_ID(blkif->domid, ACTIVE_IDX(ar));
   5.357 +        /* WPRINTK("%3u < %3lu\n", ID_TO_IDX(req_s->id), ar->id); */
   5.358  
   5.359          /* FE -> BE interposition point is here. */
   5.360          
   5.361          /* ------------------------------------------------------------- */
   5.362          /* BLKIF_OP_PROBE_HACK:                                          */
   5.363 -        /* Until we have grant tables, we need to allow the backent to   */
   5.364 -        /* map pages that are either from this domain, or more commonly  */
   5.365 -        /* from the real front end.  We achieve this in a terrible way,  */
   5.366 -        /* by passing the front end's domid allong with PROBE messages   */
   5.367 -        /* Once grant tables appear, this should all go away.            */
   5.368 +        /* Signal to the backend that we are a tap domain.               */
   5.369  
   5.370          if (req_s->operation == BLKIF_OP_PROBE) {
   5.371 -            DPRINTK("Adding FE domid to PROBE request.\n");
   5.372 -            (domid_t)(req_s->frame_and_sects[1]) = ptfe_blkif.domid;
   5.373 +            DPRINTK("Adding BLKTAP_COOKIE to PROBE request.\n");
   5.374 +            req_s->frame_and_sects[1] = BLKTAP_COOKIE;
   5.375          }
   5.376  
   5.377          /* ------------------------------------------------------------- */
   5.378 @@ -137,12 +335,9 @@ irqreturn_t blkif_ptfe_int(int irq, void
   5.379              /* In MODE_INTERCEPT_FE, map attached pages into the app vma */
   5.380              /* In MODE_COPY_FE_PAGES, copy attached pages into the app vma */
   5.381  
   5.382 -            /* XXX: mapping/copying of attached pages is still not done! */
   5.383 -
   5.384              DPRINTK("req->UFERing\n"); 
   5.385              blktap_write_fe_ring(req_s);
   5.386 -
   5.387 -
   5.388 +            notify_user = 1;
   5.389          }
   5.390  
   5.391          /* If we are not in MODE_INTERCEPT_FE or MODE_INTERCEPT_BE: */
   5.392 @@ -153,61 +348,27 @@ irqreturn_t blkif_ptfe_int(int irq, void
   5.393              /* copy the request message to the BERing */
   5.394  
   5.395              DPRINTK("blktap: FERing[%u] -> BERing[%u]\n", 
   5.396 -                    (unsigned)MASK_BLKIF_IDX(i), 
   5.397 -                    (unsigned)MASK_BLKIF_IDX(ptbe_req_prod));
   5.398 -
   5.399 -            req_d = &blk_ptbe_ring->ring[MASK_BLKIF_IDX(ptbe_req_prod)].req;
   5.400 +                    (unsigned)__SHARED_RING_MASK(BLKIF_RING, 
   5.401 +                        blktap_be_ring.sring, i), 
   5.402 +                    (unsigned)__SHARED_RING_MASK(BLKIF_RING, 
   5.403 +                        blktap_be_ring.sring, blktap_be_ring.req_prod_pvt));
   5.404              
   5.405 -            memcpy(req_d, req_s, sizeof(blkif_request_t));
   5.406 -
   5.407 -            ptbe_req_prod++;
   5.408 +            write_req_to_be_ring(req_s);
   5.409 +            notify_be = 1;
   5.410          }
   5.411      }
   5.412  
   5.413 -    ptfe_blkif.blk_req_cons = i;
   5.414 -
   5.415 -    /* If we have forwarded any responses, notify the appropriate ends. */
   5.416 -    if (notify) {
   5.417 -
   5.418 -        /* we have sent stuff to the be, notify it. */
   5.419 -        if ( !((blktap_mode & BLKTAP_MODE_INTERCEPT_FE) ||
   5.420 -               (blktap_mode & BLKTAP_MODE_INTERCEPT_BE)) ) {
   5.421 -            wmb();
   5.422 -            blk_ptbe_ring->req_prod = ptbe_req_prod;
   5.423 -
   5.424 -            notify_via_evtchn(blkif_ptbe_evtchn);
   5.425 -            DPRINTK(" -- and notified.\n");
   5.426 -        }
   5.427 -
   5.428 -        /* we sent stuff to the app, notify it. */
   5.429 -        if ( (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) ||
   5.430 -             (blktap_mode & BLKTAP_MODE_COPY_FE) ) {
   5.431 -
   5.432 -            blktap_kick_user();
   5.433 -        }
   5.434 -    }
   5.435 -
   5.436 +    blkif->blk_ring.req_cons = i;
   5.437 +    
   5.438      /* unlock rings */
   5.439      spin_unlock_irqrestore(&blkif_io_lock, flags);
   5.440 -
   5.441 -    return IRQ_HANDLED;
   5.442 -}
   5.443 -
   5.444 -inline int write_req_to_be_ring(blkif_request_t *req)
   5.445 -{
   5.446 -    blkif_request_t *req_d;
   5.447 -
   5.448 -    req_d = &blk_ptbe_ring->ring[MASK_BLKIF_IDX(ptbe_req_prod)].req;
   5.449 -    memcpy(req_d, req, sizeof(blkif_request_t));
   5.450 -    ptbe_req_prod++;
   5.451 -
   5.452 -    return 0;
   5.453 -}
   5.454 -
   5.455 -inline void kick_be_domain(void) {
   5.456 -    wmb();
   5.457 -    blk_ptbe_ring->req_prod = ptbe_req_prod;
   5.458 -    notify_via_evtchn(blkif_ptbe_evtchn);
   5.459 +    
   5.460 +    if (notify_user)
   5.461 +        blktap_kick_user();
   5.462 +    if (notify_be)
   5.463 +        kick_be_domain();
   5.464 +    
   5.465 +    return more_to_do;
   5.466  }
   5.467  
   5.468  /*-----[ Data to/from Backend (server) VM ]------------------------------*/
   5.469 @@ -216,31 +377,27 @@ inline void kick_be_domain(void) {
   5.470  irqreturn_t blkif_ptbe_int(int irq, void *dev_id, 
   5.471                                    struct pt_regs *ptregs)
   5.472  {
   5.473 -    blkif_response_t  *resp_s, *resp_d;
   5.474 -    BLKIF_RING_IDX be_rp;
   5.475 +    blkif_response_t  *resp_s;
   5.476 +    blkif_t *blkif;
   5.477 +    RING_IDX rp, i;
   5.478      unsigned long flags;
   5.479 -    int notify;
   5.480 -    unsigned long i;
   5.481 -    active_req_t *ar;
   5.482  
   5.483      DPRINTK("PT got BE interrupt.\n");
   5.484  
   5.485      /* lock both rings */
   5.486      spin_lock_irqsave(&blkif_io_lock, flags);
   5.487      
   5.488 -    /* While there are RESPONSES on BERing: */
   5.489 -    be_rp = blk_ptbe_ring->resp_prod;
   5.490 +    rp = blktap_be_ring.sring->rsp_prod;
   5.491      rmb();
   5.492 -    notify = (ptbe_resp_cons != be_rp);
   5.493 -    
   5.494 -    for ( i = ptbe_resp_cons; i != be_rp; i++ )
   5.495 +      
   5.496 +    for ( i = blktap_be_ring.rsp_cons; i != rp; i++)
   5.497      {
   5.498 -        /* BE -> FE interposition point is here. */
   5.499 +        resp_s = RING_GET_RESPONSE(BLKIF_RING, &blktap_be_ring, i);
   5.500          
   5.501 -        /* Get the next response */
   5.502 -        resp_s = &blk_ptbe_ring->ring[MASK_BLKIF_IDX(i)].resp;
   5.503 +        /* BE -> FE interposition point is here. */
   5.504      
   5.505 -       
   5.506 +        blkif = active_reqs[ID_TO_IDX(resp_s->id)].blkif;
   5.507 +        
   5.508          /* If we are in MODE_INTERCEPT_BE or MODE_COPY_BE: */
   5.509          if ( (blktap_mode & BLKTAP_MODE_INTERCEPT_BE) ||
   5.510               (blktap_mode & BLKTAP_MODE_COPY_BE) ) {
   5.511 @@ -249,10 +406,9 @@ irqreturn_t blkif_ptbe_int(int irq, void
   5.512              /* In MODE_INTERCEPT_BE, map attached pages into the app vma */
   5.513              /* In MODE_COPY_BE_PAGES, copy attached pages into the app vma */
   5.514  
   5.515 -            /* XXX: copy/map the attached page! */
   5.516 -
   5.517              DPRINTK("rsp->UBERing\n"); 
   5.518              blktap_write_be_ring(resp_s);
   5.519 +            blktap_kick_user();
   5.520  
   5.521          }
   5.522         
   5.523 @@ -264,254 +420,49 @@ irqreturn_t blkif_ptbe_int(int irq, void
   5.524              /* Copy the response message to FERing */
   5.525           
   5.526              DPRINTK("blktap: BERing[%u] -> FERing[%u]\n", 
   5.527 -                    (unsigned) MASK_BLKIF_IDX(i), 
   5.528 -                    (unsigned) MASK_BLKIF_IDX(ptfe_blkif.blk_resp_prod));
   5.529 +                    (unsigned)__SHARED_RING_MASK(BLKIF_RING, 
   5.530 +                        blkif->blk_ring.sring, i), 
   5.531 +                    (unsigned)__SHARED_RING_MASK(BLKIF_RING, 
   5.532 +                        blkif->blk_ring.sring, 
   5.533 +                        blkif->blk_ring.rsp_prod_pvt));
   5.534  
   5.535 -            /* remap id, and free the active req. blkif lookup goes here too.*/
   5.536 -            ar = &active_reqs[resp_s->id];
   5.537 -            DPRINTK("%3lu > %3lu\n", resp_s->id, ar->id);
   5.538 -            resp_s->id = ar->id;
   5.539 -            free_active_req(ar);
   5.540 -           
   5.541 -            resp_d = &ptfe_blkif.blk_ring_base->ring[
   5.542 -                MASK_BLKIF_IDX(ptfe_blkif.blk_resp_prod)].resp;
   5.543 -
   5.544 -            memcpy(resp_d, resp_s, sizeof(blkif_response_t));
   5.545 -            
   5.546 -            ptfe_blkif.blk_resp_prod++;
   5.547 +            write_resp_to_fe_ring(blkif, resp_s);
   5.548 +            kick_fe_domain(blkif);
   5.549  
   5.550          }
   5.551      }
   5.552 -
   5.553 -    ptbe_resp_cons = i;
   5.554      
   5.555 -    /* If we have forwarded any responses, notify the apropriate domains. */
   5.556 -    if (notify) {
   5.557 -
   5.558 -        /* we have sent stuff to the fe.  notify it. */
   5.559 -        if ( !((blktap_mode & BLKTAP_MODE_INTERCEPT_BE) ||
   5.560 -               (blktap_mode & BLKTAP_MODE_INTERCEPT_FE)) ) {
   5.561 -            wmb();
   5.562 -            ptfe_blkif.blk_ring_base->resp_prod = ptfe_blkif.blk_resp_prod;
   5.563 -        
   5.564 -            notify_via_evtchn(ptfe_blkif.evtchn);
   5.565 -            DPRINTK(" -- and notified.\n");
   5.566 -        }
   5.567 -
   5.568 -        /* we sent stuff to the app, notify it. */
   5.569 -        if ( (blktap_mode & BLKTAP_MODE_INTERCEPT_BE) ||
   5.570 -             (blktap_mode & BLKTAP_MODE_COPY_BE) ) {
   5.571 -
   5.572 -            blktap_kick_user();
   5.573 -        }
   5.574 -    }
   5.575 +    blktap_be_ring.rsp_cons = i;
   5.576 +    
   5.577  
   5.578      spin_unlock_irqrestore(&blkif_io_lock, flags);
   5.579 +    
   5.580      return IRQ_HANDLED;
   5.581  }
   5.582  
   5.583 -inline int write_resp_to_fe_ring(blkif_response_t *rsp)
   5.584 -{
   5.585 -    blkif_response_t *resp_d;
   5.586 -    active_req_t *ar;
   5.587 -    
   5.588 -    /* remap id, and free the active req. blkif lookup goes here too.*/
   5.589 -    ar = &active_reqs[rsp->id];
   5.590 -    DPRINTK("%3lu > %3lu\n", rsp->id, ar->id);
   5.591 -    rsp->id = ar->id;
   5.592 -    free_active_req(ar);
   5.593 -            
   5.594 -    resp_d = &ptfe_blkif.blk_ring_base->ring[
   5.595 -        MASK_BLKIF_IDX(ptfe_blkif.blk_resp_prod)].resp;
   5.596 -
   5.597 -    memcpy(resp_d, rsp, sizeof(blkif_response_t));
   5.598 -    ptfe_blkif.blk_resp_prod++;
   5.599 -
   5.600 -    return 0;
   5.601 -}
   5.602 -
   5.603 -inline void kick_fe_domain(void) {
   5.604 -    wmb();
   5.605 -    ptfe_blkif.blk_ring_base->resp_prod = ptfe_blkif.blk_resp_prod;
   5.606 -    notify_via_evtchn(ptfe_blkif.evtchn);
   5.607 -    
   5.608 -}
   5.609 -
   5.610 -static inline void flush_requests(void)
   5.611 -{
   5.612 -    wmb(); /* Ensure that the frontend can see the requests. */
   5.613 -    blk_ptbe_ring->req_prod = ptbe_req_prod;
   5.614 -    notify_via_evtchn(blkif_ptbe_evtchn);
   5.615 -}
   5.616 -
   5.617 -/*-----[ Data to/from user space ]----------------------------------------*/
   5.618 -
   5.619 -
   5.620 -int blktap_write_fe_ring(blkif_request_t *req)
   5.621 -{
   5.622 -    blkif_request_t *target;
   5.623 -    int error, i;
   5.624 -
   5.625 -    /*
   5.626 -     * This is called to pass a request from the real frontend domain's
   5.627 -     * blkif ring to the character device.
   5.628 -     */
   5.629 -
   5.630 -    if ( ! blktap_ring_ok ) {
   5.631 -        DPRINTK("blktap: fe_ring not ready for a request!\n");
   5.632 -        return 0;
   5.633 -    }
   5.634 -
   5.635 -    if ( BLKTAP_RING_FULL(RING(&fe_ring)) ) {
   5.636 -        DPRINTK("blktap: fe_ring is full, can't add.\n");
   5.637 -        return 0;
   5.638 -    }
   5.639 -
   5.640 -    target = &fe_ring.ring->ring[MASK_BLKIF_IDX(fe_ring.req_prod)].req;
   5.641 -    memcpy(target, req, sizeof(*req));
   5.642 -
   5.643 -/* maybe move this stuff out into a seperate func ------------------- */
   5.644 -
   5.645 -    /*
   5.646 -     * For now, map attached page into a fixed position into the vma.
   5.647 -     * XXX: make this map to a free page.
   5.648 -     */
   5.649 -
   5.650 -    /* Attempt to map the foreign pages directly in to the application */
   5.651 -    for (i=0; i<target->nr_segments; i++) {
   5.652 -
   5.653 -        /* get an unused virtual address from the char device */
   5.654 -        /* store the old page address */
   5.655 -        /* replace the address with the virtual address */
   5.656 -
   5.657 -        /* blktap_vma->vm_start+((2+i)*PAGE_SIZE) */
   5.658 -
   5.659 -        error = direct_remap_area_pages(blktap_vma->vm_mm, 
   5.660 -                                        MMAP_VADDR(req->id, i), 
   5.661 -                                        target->frame_and_sects[0] & PAGE_MASK,
   5.662 -                                        PAGE_SIZE,
   5.663 -                                        blktap_vma->vm_page_prot,
   5.664 -                                        ptfe_blkif.domid);
   5.665 -        if ( error != 0 ) {
   5.666 -            printk(KERN_INFO "remapping attached page failed! (%d)\n", error);
   5.667 -            return 0;
   5.668 -        }
   5.669 -    }
   5.670 -    /* fix the address of the attached page in the message. */
   5.671 -    /* TODO:      preserve the segment number stuff here... */
   5.672 -    /* target->frame_and_sects[0] = blktap_vma->vm_start + PAGE_SIZE;*/
   5.673 -/* ------------------------------------------------------------------ */
   5.674 -
   5.675 -    
   5.676 -    fe_ring.req_prod++;
   5.677 -
   5.678 -    return 0;
   5.679 -}
   5.680 -
   5.681 -int blktap_write_be_ring(blkif_response_t *rsp)
   5.682 -{
   5.683 -    blkif_response_t *target;
   5.684 +/* Debug : print the current ring indices. */
   5.685  
   5.686 -    /*
   5.687 -     * This is called to pass a request from the real backend domain's
   5.688 -     * blkif ring to the character device.
   5.689 -     */
   5.690 -
   5.691 -    if ( ! blktap_ring_ok ) {
   5.692 -        DPRINTK("blktap: be_ring not ready for a request!\n");
   5.693 -        return 0;
   5.694 -    }
   5.695 -
   5.696 -    if ( BLKTAP_RING_FULL(RING(&be_ring)) ) {
   5.697 -        DPRINTK("blktap: be_ring is full, can't add.\n");
   5.698 -        return 0;
   5.699 -    }
   5.700 -
   5.701 -    target = &be_ring.ring->ring[MASK_BLKIF_IDX(be_ring.rsp_prod)].resp;
   5.702 -    memcpy(target, rsp, sizeof(*rsp));
   5.703 -
   5.704 -
   5.705 -    /* XXX: map attached pages and fix-up addresses in the copied address. */
   5.706 -
   5.707 -    be_ring.rsp_prod++;
   5.708 -
   5.709 -    return 0;
   5.710 -}
   5.711 -
   5.712 -int blktap_read_fe_ring(void)
   5.713 +void print_vm_ring_idxs(void)
   5.714  {
   5.715 -    /* This is called to read responses from the UFE ring. */
   5.716 -
   5.717 -    BLKIF_RING_IDX fe_rp;
   5.718 -    unsigned long i;
   5.719 -    int notify;
   5.720 -
   5.721 -    DPRINTK("blktap_read_fe_ring()\n");
   5.722 -
   5.723 -    fe_rp = fe_ring.ring->resp_prod;
   5.724 -    rmb();
   5.725 -    notify = (fe_rp != fe_ring.rsp_cons);
   5.726 -
   5.727 -    /* if we are forwarding from UFERring to FERing */
   5.728 -    if (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) {
   5.729 -
   5.730 -        /* for each outstanding message on the UFEring  */
   5.731 -        for ( i = fe_ring.rsp_cons; i != fe_rp; i++ ) {
   5.732 -
   5.733 -            /* XXX: remap pages on that message as necessary */
   5.734 -            /* copy the message to the UBEring */
   5.735 -
   5.736 -            DPRINTK("resp->fe_ring\n");
   5.737 -            write_resp_to_fe_ring(&fe_ring.ring->ring[MASK_BLKIF_IDX(i)].resp);
   5.738 -        }
   5.739 -    
   5.740 -        fe_ring.rsp_cons = fe_rp;
   5.741 -
   5.742 -        /* notify the fe if necessary */
   5.743 -        if ( notify ) {
   5.744 -            DPRINTK("kick_fe_domain()\n");
   5.745 -            kick_fe_domain();
   5.746 -        }
   5.747 +    int i;
   5.748 +    blkif_t *blkif;
   5.749 +            
   5.750 +    WPRINTK("FE Rings: \n---------\n");
   5.751 +    for ( i = 0; i < 50; i++) { 
   5.752 +        blkif = blkif_find_by_handle((domid_t)i, 0);
   5.753 +        if (blkif != NULL)
   5.754 +            WPRINTK("%2d: req_cons: %2d, rsp_prod_prv: %2d "
   5.755 +                "| req_prod: %2d, rsp_prod: %2d\n", i, 
   5.756 +                blkif->blk_ring.req_cons,
   5.757 +                blkif->blk_ring.rsp_prod_pvt,
   5.758 +                blkif->blk_ring.sring->req_prod,
   5.759 +                blkif->blk_ring.sring->rsp_prod);
   5.760      }
   5.761 -
   5.762 -    return 0;
   5.763 -}
   5.764 -
   5.765 -int blktap_read_be_ring(void)
   5.766 -{
   5.767 -    /* This is called to read responses from the UBE ring. */
   5.768 -
   5.769 -    BLKIF_RING_IDX be_rp;
   5.770 -    unsigned long i;
   5.771 -    int notify;
   5.772 -
   5.773 -    DPRINTK("blktap_read_be_ring()\n");
   5.774 -
   5.775 -    be_rp = be_ring.ring->req_prod;
   5.776 -    rmb();
   5.777 -    notify = (be_rp != be_ring.req_cons);
   5.778 -
   5.779 -    /* if we are forwarding from UFERring to FERing */
   5.780 -    if (blktap_mode & BLKTAP_MODE_INTERCEPT_BE) {
   5.781 -
   5.782 -        /* for each outstanding message on the UFEring  */
   5.783 -        for ( i = be_ring.req_cons; i != be_rp; i++ ) {
   5.784 -
   5.785 -            /* XXX: remap pages on that message as necessary */
   5.786 -            /* copy the message to the UBEring */
   5.787 -
   5.788 -            DPRINTK("req->be_ring\n");
   5.789 -            write_req_to_be_ring(&be_ring.ring->ring[MASK_BLKIF_IDX(i)].req);
   5.790 -        }
   5.791 -    
   5.792 -        be_ring.req_cons = be_rp;
   5.793 -
   5.794 -        /* notify the fe if necessary */
   5.795 -        if ( notify ) {
   5.796 -            DPRINTK("kick_be_domain()\n");
   5.797 -            kick_be_domain();
   5.798 -        }
   5.799 -    }
   5.800 -
   5.801 -    return 0;
   5.802 -}
   5.803 +    WPRINTK("BE Ring: \n--------\n");
   5.804 +    WPRINTK("BE: rsp_cons: %2d, req_prod_prv: %2d "
   5.805 +        "| req_prod: %2d, rsp_prod: %2d\n",
   5.806 +        blktap_be_ring.rsp_cons,
   5.807 +        blktap_be_ring.req_prod_pvt,
   5.808 +        blktap_be_ring.sring->req_prod,
   5.809 +        blktap_be_ring.sring->rsp_prod);
   5.810 +}        
     6.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_userdev.c	Tue Jan 18 08:28:11 2005 +0000
     6.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blktap/blktap_userdev.c	Wed Jan 19 14:11:35 2005 +0000
     6.3 @@ -37,6 +37,10 @@ struct vm_area_struct *blktap_vma;
     6.4  unsigned long mmap_vstart;
     6.5  unsigned long rings_vstart;
     6.6  
     6.7 +/* Rings up to user space. */
     6.8 +static blkif_front_ring_t blktap_ufe_ring;
     6.9 +static blkif_back_ring_t  blktap_ube_ring;
    6.10 +
    6.11  /* -------[ blktap vm ops ]------------------------------------------- */
    6.12  
    6.13  static struct page *blktap_nopage(struct vm_area_struct *vma,
    6.14 @@ -61,41 +65,39 @@ struct vm_operations_struct blktap_vm_op
    6.15  
    6.16  static int blktap_open(struct inode *inode, struct file *filp)
    6.17  {
    6.18 +    blkif_sring_t *sring;
    6.19 +    
    6.20      if ( test_and_set_bit(0, &blktap_dev_inuse) )
    6.21          return -EBUSY;
    6.22  
    6.23      printk(KERN_ALERT "blktap open.\n");
    6.24  
    6.25      /* Allocate the fe ring. */
    6.26 -    fe_ring.ring = (blkif_ring_t *)get_zeroed_page(GFP_KERNEL);
    6.27 -    if (fe_ring.ring == NULL)
    6.28 +    sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
    6.29 +    if (sring == NULL)
    6.30          goto fail_nomem;
    6.31  
    6.32 -    SetPageReserved(virt_to_page(fe_ring.ring));
    6.33 +    SetPageReserved(virt_to_page(sring));
    6.34      
    6.35 -    fe_ring.ring->req_prod = fe_ring.ring->resp_prod
    6.36 -                           = fe_ring.req_prod
    6.37 -                           = fe_ring.rsp_cons
    6.38 -                           = 0;
    6.39 +    SHARED_RING_INIT(BLKIF_RING, sring);
    6.40 +    FRONT_RING_INIT(BLKIF_RING, &blktap_ufe_ring, sring);
    6.41  
    6.42      /* Allocate the be ring. */
    6.43 -    be_ring.ring = (blkif_ring_t *)get_zeroed_page(GFP_KERNEL);
    6.44 -    if (be_ring.ring == NULL)
    6.45 +    sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
    6.46 +    if (sring == NULL)
    6.47          goto fail_free_fe;
    6.48  
    6.49 -    SetPageReserved(virt_to_page(be_ring.ring));
    6.50 +    SetPageReserved(virt_to_page(sring));
    6.51      
    6.52 -    be_ring.ring->req_prod = be_ring.ring->resp_prod
    6.53 -                           = be_ring.rsp_prod
    6.54 -                           = be_ring.req_cons
    6.55 -                           = 0;
    6.56 +    SHARED_RING_INIT(BLKIF_RING, sring);
    6.57 +    BACK_RING_INIT(BLKIF_RING, &blktap_ube_ring, sring);
    6.58  
    6.59      DPRINTK(KERN_ALERT "blktap open.\n");
    6.60  
    6.61      return 0;
    6.62  
    6.63   fail_free_fe:
    6.64 -    free_page( (unsigned long) fe_ring.ring);
    6.65 +    free_page( (unsigned long) blktap_ufe_ring.sring);
    6.66  
    6.67   fail_nomem:
    6.68      return -ENOMEM;
    6.69 @@ -109,11 +111,11 @@ static int blktap_release(struct inode *
    6.70      printk(KERN_ALERT "blktap closed.\n");
    6.71  
    6.72      /* Free the ring page. */
    6.73 -    ClearPageReserved(virt_to_page(fe_ring.ring));
    6.74 -    free_page((unsigned long) fe_ring.ring);
    6.75 +    ClearPageReserved(virt_to_page(blktap_ufe_ring.sring));
    6.76 +    free_page((unsigned long) blktap_ufe_ring.sring);
    6.77  
    6.78 -    ClearPageReserved(virt_to_page(be_ring.ring));
    6.79 -    free_page((unsigned long) be_ring.ring);
    6.80 +    ClearPageReserved(virt_to_page(blktap_ube_ring.sring));
    6.81 +    free_page((unsigned long) blktap_ube_ring.sring);
    6.82      
    6.83      return 0;
    6.84  }
    6.85 @@ -146,16 +148,18 @@ static int blktap_mmap(struct file *filp
    6.86      /* not sure if I really need to do this... */
    6.87      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    6.88  
    6.89 -    DPRINTK("Mapping be_ring page %lx.\n", __pa(be_ring.ring));
    6.90 -    if (remap_page_range(vma, vma->vm_start, __pa(be_ring.ring), PAGE_SIZE, 
    6.91 -                         vma->vm_page_prot)) {
    6.92 -        printk(KERN_ERR "be_ring: remap_page_range failure!\n");
    6.93 +    DPRINTK("Mapping be_ring page %lx.\n", __pa(blktap_ube_ring.sring));
    6.94 +    if (remap_page_range(vma, vma->vm_start, 
    6.95 +                         __pa(blktap_ube_ring.sring), 
    6.96 +                         PAGE_SIZE, vma->vm_page_prot)) {
    6.97 +        WPRINTK("be_ring: remap_page_range failure!\n");
    6.98      }
    6.99  
   6.100 -    DPRINTK("Mapping fe_ring page %lx.\n", __pa(fe_ring.ring));
   6.101 -    if (remap_page_range(vma, vma->vm_start + PAGE_SIZE, __pa(fe_ring.ring), 
   6.102 +    DPRINTK("Mapping fe_ring page %lx.\n", __pa(blktap_ufe_ring.sring));
   6.103 +    if (remap_page_range(vma, vma->vm_start + PAGE_SIZE, 
   6.104 +                         __pa(blktap_ufe_ring.sring), 
   6.105                           PAGE_SIZE, vma->vm_page_prot)) {
   6.106 -        printk(KERN_ERR "fe_ring: remap_page_range failure!\n");
   6.107 +        WPRINTK("fe_ring: remap_page_range failure!\n");
   6.108      }
   6.109  
   6.110      blktap_vma = vma;
   6.111 @@ -181,7 +185,24 @@ static int blktap_ioctl(struct inode *in
   6.112              printk(KERN_INFO "blktap: set mode to %lx\n", arg);
   6.113              return 0;
   6.114          }
   6.115 -        /* XXX: return a more meaningful error case here. */
   6.116 +    case BLKTAP_IOCTL_PRINT_IDXS:
   6.117 +        {
   6.118 +            print_vm_ring_idxs();
   6.119 +            WPRINTK("User Rings: \n-----------\n");
   6.120 +            WPRINTK("UF: rsp_cons: %2d, req_prod_prv: %2d "
   6.121 +                            "| req_prod: %2d, rsp_prod: %2d\n",
   6.122 +                            blktap_ufe_ring.rsp_cons,
   6.123 +                            blktap_ufe_ring.req_prod_pvt,
   6.124 +                            blktap_ufe_ring.sring->req_prod,
   6.125 +                            blktap_ufe_ring.sring->rsp_prod);
   6.126 +            WPRINTK("UB: req_cons: %2d, rsp_prod_prv: %2d "
   6.127 +                            "| req_prod: %2d, rsp_prod: %2d\n",
   6.128 +                            blktap_ube_ring.req_cons,
   6.129 +                            blktap_ube_ring.rsp_prod_pvt,
   6.130 +                            blktap_ube_ring.sring->req_prod,
   6.131 +                            blktap_ube_ring.sring->rsp_prod);
   6.132 +            
   6.133 +        }
   6.134      }
   6.135      return -ENOIOCTLCMD;
   6.136  }
   6.137 @@ -190,11 +211,11 @@ static unsigned int blktap_poll(struct f
   6.138  {
   6.139          poll_wait(file, &blktap_wait, wait);
   6.140  
   6.141 -        if ( (fe_ring.req_prod != fe_ring.ring->req_prod) ||
   6.142 -             (be_ring.rsp_prod != be_ring.ring->resp_prod) ) {
   6.143 +        if ( RING_HAS_UNPUSHED_REQUESTS(BLKIF_RING, &blktap_ufe_ring) ||
   6.144 +             RING_HAS_UNPUSHED_RESPONSES(BLKIF_RING, &blktap_ube_ring) ) {
   6.145  
   6.146 -            fe_ring.ring->req_prod = fe_ring.req_prod;
   6.147 -            be_ring.ring->resp_prod = be_ring.rsp_prod;
   6.148 +            RING_PUSH_REQUESTS(BLKIF_RING, &blktap_ufe_ring);
   6.149 +            RING_PUSH_RESPONSES(BLKIF_RING, &blktap_ube_ring);
   6.150              return POLLIN | POLLRDNORM;
   6.151          }
   6.152  
   6.153 @@ -215,7 +236,149 @@ static struct file_operations blktap_fop
   6.154      release:  blktap_release,
   6.155      mmap:     blktap_mmap,
   6.156  };
   6.157 +    
   6.158 +/*-----[ Data to/from user space ]----------------------------------------*/
   6.159  
   6.160 +
   6.161 +int blktap_write_fe_ring(blkif_request_t *req)
   6.162 +{
   6.163 +    blkif_request_t *target;
   6.164 +    int error, i;
   6.165 +
   6.166 +    /*
   6.167 +     * This is called to pass a request from the real frontend domain's
   6.168 +     * blkif ring to the character device.
   6.169 +     */
   6.170 +
   6.171 +    if ( ! blktap_ring_ok ) {
   6.172 +        DPRINTK("blktap: ufe_ring not ready for a request!\n");
   6.173 +        return 0;
   6.174 +    }
   6.175 +
   6.176 +    if ( RING_FULL(BLKIF_RING, &blktap_ufe_ring) ) {
   6.177 +        DPRINTK("blktap: fe_ring is full, can't add.\n");
   6.178 +        return 0;
   6.179 +    }
   6.180 +
   6.181 +    //target = RING_NEXT_EMPTY_REQUEST(BLKIF_RING, &blktap_ufe_ring);
   6.182 +    target = RING_GET_REQUEST(BLKIF_RING, &blktap_ufe_ring,
   6.183 +            blktap_ufe_ring.req_prod_pvt);
   6.184 +    memcpy(target, req, sizeof(*req));
   6.185 +
   6.186 +    /* Attempt to map the foreign pages directly in to the application */
   6.187 +    for (i=0; i<target->nr_segments; i++) {
   6.188 +
   6.189 +        error = direct_remap_area_pages(blktap_vma->vm_mm, 
   6.190 +                                        MMAP_VADDR(ID_TO_IDX(req->id), i), 
   6.191 +                                        target->frame_and_sects[0] & PAGE_MASK,
   6.192 +                                        PAGE_SIZE,
   6.193 +                                        blktap_vma->vm_page_prot,
   6.194 +                                        ID_TO_DOM(req->id));
   6.195 +        if ( error != 0 ) {
   6.196 +            printk(KERN_INFO "remapping attached page failed! (%d)\n", error);
   6.197 +            /* the request is now dropped on the floor. */
   6.198 +            return 0;
   6.199 +        }
   6.200 +    }
   6.201 +    
   6.202 +    blktap_ufe_ring.req_prod_pvt++;
   6.203 +    
   6.204 +    return 0;
   6.205 +}
   6.206 +
   6.207 +int blktap_write_be_ring(blkif_response_t *rsp)
   6.208 +{
   6.209 +    blkif_response_t *target;
   6.210 +
   6.211 +    /*
   6.212 +     * This is called to pass a request from the real backend domain's
   6.213 +     * blkif ring to the character device.
   6.214 +     */
   6.215 +
   6.216 +    if ( ! blktap_ring_ok ) {
   6.217 +        DPRINTK("blktap: be_ring not ready for a request!\n");
   6.218 +        return 0;
   6.219 +    }
   6.220 +
   6.221 +    /* No test for fullness in the response direction. */
   6.222 +
   6.223 +    //target = RING_NEXT_EMPTY_RESPONSE(BLKIF_RING, &blktap_ube_ring);
   6.224 +    target = RING_GET_RESPONSE(BLKIF_RING, &blktap_ube_ring,
   6.225 +            blktap_ube_ring.rsp_prod_pvt);
   6.226 +    memcpy(target, rsp, sizeof(*rsp));
   6.227 +
   6.228 +    /* no mapping -- pages were mapped in blktap_write_fe_ring() */
   6.229 +
   6.230 +    blktap_ube_ring.rsp_prod_pvt++;
   6.231 +    
   6.232 +    return 0;
   6.233 +}
   6.234 +
   6.235 +int blktap_read_fe_ring(void)
   6.236 +{
   6.237 +    /* This is called to read responses from the UFE ring. */
   6.238 +
   6.239 +    RING_IDX i, rp;
   6.240 +    blkif_response_t *resp_s;
   6.241 +    blkif_t *blkif;
   6.242 +    active_req_t *ar;
   6.243 +
   6.244 +    DPRINTK("blktap_read_fe_ring()\n");
   6.245 +
   6.246 +    /* if we are forwarding from UFERring to FERing */
   6.247 +    if (blktap_mode & BLKTAP_MODE_INTERCEPT_FE) {
   6.248 +
   6.249 +        /* for each outstanding message on the UFEring  */
   6.250 +        //RING_FOREACH_RESPONSE(BLKIF_RING, &blktap_ufe_ring, prod, resp_s) {
   6.251 +        rp = blktap_ufe_ring.sring->rsp_prod;
   6.252 +        rmb();
   6.253 +        
   6.254 +        for ( i = blktap_ufe_ring.rsp_cons; i != rp; i++ )
   6.255 +        {
   6.256 +            resp_s = RING_GET_RESPONSE(BLKIF_RING, &blktap_ufe_ring, i);
   6.257 +            
   6.258 +            DPRINTK("resp->fe_ring\n");
   6.259 +            ar = lookup_active_req(ID_TO_IDX(resp_s->id));
   6.260 +            blkif = ar->blkif;
   6.261 +            write_resp_to_fe_ring(blkif, resp_s);
   6.262 +            kick_fe_domain(blkif);
   6.263 +        }
   6.264 +        
   6.265 +        blktap_ufe_ring.rsp_cons = i;
   6.266 +    }
   6.267 +    return 0;
   6.268 +}
   6.269 +
   6.270 +int blktap_read_be_ring(void)
   6.271 +{
   6.272 +    /* This is called to read requests from the UBE ring. */
   6.273 +
   6.274 +    RING_IDX i, rp;
   6.275 +    blkif_request_t *req_s;
   6.276 +
   6.277 +    DPRINTK("blktap_read_be_ring()\n");
   6.278 +
   6.279 +    /* if we are forwarding from UFERring to FERing */
   6.280 +    if (blktap_mode & BLKTAP_MODE_INTERCEPT_BE) {
   6.281 +
   6.282 +        /* for each outstanding message on the UFEring  */
   6.283 +        //RING_FOREACH_REQUEST(BLKIF_RING, &blktap_ube_ring, prod, req_s) {
   6.284 +        rp = blktap_ube_ring.sring->req_prod;
   6.285 +        rmb();
   6.286 +        for ( i = blktap_ube_ring.req_cons; i != rp; i++ )
   6.287 +        {
   6.288 +            req_s = RING_GET_REQUEST(BLKIF_RING, &blktap_ube_ring, i);
   6.289 +
   6.290 +            DPRINTK("req->be_ring\n");
   6.291 +            write_req_to_be_ring(req_s);
   6.292 +            kick_be_domain();
   6.293 +        }
   6.294 +        
   6.295 +        blktap_ube_ring.req_cons = i;
   6.296 +    }
   6.297 +
   6.298 +    return 0;
   6.299 +}
   6.300  /* -------[ blktap module setup ]------------------------------------- */
   6.301  
   6.302  static struct miscdevice blktap_miscdev = {
     7.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c	Tue Jan 18 08:28:11 2005 +0000
     7.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c	Wed Jan 19 14:11:35 2005 +0000
     7.3 @@ -14,8 +14,8 @@
     7.4  #include <asm-xen/balloon.h>
     7.5  #include <asm-xen/evtchn.h>
     7.6  
     7.7 +static void netif_idx_release(u16 pending_idx);
     7.8  static void netif_page_release(struct page *page);
     7.9 -static void netif_skb_release(struct sk_buff *skb);
    7.10  static void make_tx_response(netif_t *netif, 
    7.11                               u16      id,
    7.12                               s8       st);
    7.13 @@ -412,7 +412,7 @@ static void net_tx_action(unsigned long 
    7.14          mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT;
    7.15          mcl[0].args[1] = 0;
    7.16          mcl[0].args[2] = 0;
    7.17 -        mcl++;        
    7.18 +        mcl++;     
    7.19      }
    7.20  
    7.21      mcl[-1].args[2] = UVMF_FLUSH_TLB;
    7.22 @@ -532,7 +532,7 @@ static void net_tx_action(unsigned long 
    7.23  
    7.24          pending_idx = pending_ring[MASK_PEND_IDX(pending_cons)];
    7.25  
    7.26 -        data_len = txreq.size > PKT_PROT_LEN ? PKT_PROT_LEN : txreq.size;
    7.27 +        data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
    7.28  
    7.29          if ( unlikely((skb = alloc_skb(data_len+16, GFP_ATOMIC)) == NULL) )
    7.30          {
    7.31 @@ -593,14 +593,15 @@ static void net_tx_action(unsigned long 
    7.32          phys_to_machine_mapping[__pa(MMAP_VADDR(pending_idx)) >> PAGE_SHIFT] =
    7.33              FOREIGN_FRAME(txreq.addr >> PAGE_SHIFT);
    7.34  
    7.35 -        data_len = txreq.size > PKT_PROT_LEN ? PKT_PROT_LEN : txreq.size;
    7.36 +        data_len = (txreq.size > PKT_PROT_LEN) ? PKT_PROT_LEN : txreq.size;
    7.37  
    7.38          __skb_put(skb, data_len);
    7.39          memcpy(skb->data, 
    7.40                 (void *)(MMAP_VADDR(pending_idx)|(txreq.addr&~PAGE_MASK)),
    7.41                 data_len);
    7.42  
    7.43 -        if (data_len < txreq.size) {
    7.44 +        if ( data_len < txreq.size )
    7.45 +        {
    7.46              /* Append the packet payload as a fragment. */
    7.47              skb_shinfo(skb)->frags[0].page        = 
    7.48                  virt_to_page(MMAP_VADDR(pending_idx));
    7.49 @@ -608,10 +609,11 @@ static void net_tx_action(unsigned long 
    7.50              skb_shinfo(skb)->frags[0].page_offset = 
    7.51                  (txreq.addr + data_len) & ~PAGE_MASK;
    7.52              skb_shinfo(skb)->nr_frags = 1;
    7.53 -        } else {
    7.54 -            skb_shinfo(skb)->frags[0].page        = 
    7.55 -                virt_to_page(MMAP_VADDR(pending_idx));
    7.56 -            skb->destructor = netif_skb_release;
    7.57 +        }
    7.58 +        else
    7.59 +        {
    7.60 +            /* Schedule a response immediately. */
    7.61 +            netif_idx_release(pending_idx);
    7.62          }
    7.63  
    7.64          skb->data_len  = txreq.size - data_len;
    7.65 @@ -652,14 +654,6 @@ static void netif_page_release(struct pa
    7.66      netif_idx_release(pending_idx);
    7.67  }
    7.68  
    7.69 -static void netif_skb_release(struct sk_buff *skb)
    7.70 -{
    7.71 -    struct page *page = skb_shinfo(skb)->frags[0].page;
    7.72 -    u16 pending_idx = page - virt_to_page(mmap_vstart);
    7.73 -
    7.74 -    netif_idx_release(pending_idx);
    7.75 -}
    7.76 -
    7.77  irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
    7.78  {
    7.79      netif_t *netif = dev_id;
    7.80 @@ -748,7 +742,7 @@ static int __init netback_init(void)
    7.81      struct page *page;
    7.82  
    7.83      if ( !(xen_start_info.flags & SIF_NET_BE_DOMAIN) &&
    7.84 -	 !(xen_start_info.flags & SIF_INITDOMAIN) )
    7.85 +         !(xen_start_info.flags & SIF_INITDOMAIN) )
    7.86          return 0;
    7.87  
    7.88      printk("Initialising Xen netif backend\n");
     8.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Tue Jan 18 08:28:11 2005 +0000
     8.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c	Wed Jan 19 14:11:35 2005 +0000
     8.3 @@ -273,7 +273,6 @@ static int send_fake_arp(struct net_devi
     8.4                       dst_ip, dev, src_ip,
     8.5                       /*dst_hw*/ NULL, /*src_hw*/ NULL, 
     8.6                       /*target_hw*/ dev->dev_addr);
     8.7 -    printk(KERN_ALERT "ARP sent on %08x %08x %p\n", dst_ip, src_ip, skb);
     8.8      if ( skb == NULL )
     8.9          return -ENOMEM;
    8.10  
     9.1 --- a/xen/arch/x86/e820.c	Tue Jan 18 08:28:11 2005 +0000
     9.2 +++ b/xen/arch/x86/e820.c	Wed Jan 19 14:11:35 2005 +0000
     9.3 @@ -309,8 +309,33 @@ static void __init machine_specific_memo
     9.4      struct e820entry *raw, int raw_nr)
     9.5  {
     9.6      char nr = (char)raw_nr;
     9.7 +    int i;
     9.8 +
     9.9      sanitize_e820_map(raw, &nr);
    9.10 +
    9.11      (void)copy_e820_map(raw, nr);
    9.12 +
    9.13 +#ifdef __i386__
    9.14 +    /* 32-bit systems restricted to a 4GB physical memory map. */
    9.15 +    for ( i = 0; i < e820.nr_map; i++ )
    9.16 +    {
    9.17 +        if ( (e820.map[i].addr + e820.map[i].size) <= 0x100000000ULL )
    9.18 +            continue;
    9.19 +        printk("WARNING: Only the first 4GB of the physical memory map "
    9.20 +               "can be accessed\n"
    9.21 +               "         by Xen in 32-bit mode. "
    9.22 +               "Truncating the memory map...\n");
    9.23 +        if ( e820.map[i].addr >= 0x100000000ULL )
    9.24 +        {
    9.25 +            e820.nr_map = i;
    9.26 +        }
    9.27 +        else
    9.28 +        {
    9.29 +            e820.map[i].size = 0x100000000ULL - e820.map[i].addr;
    9.30 +            e820.nr_map = i + 1;                
    9.31 +        }            
    9.32 +    }
    9.33 +#endif
    9.34  }
    9.35  
    9.36  unsigned long init_e820(struct e820entry *raw, int raw_nr)
    10.1 --- a/xen/common/dom0_ops.c	Tue Jan 18 08:28:11 2005 +0000
    10.2 +++ b/xen/common/dom0_ops.c	Wed Jan 19 14:11:35 2005 +0000
    10.3 @@ -662,7 +662,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    10.4      {
    10.5          struct domain *d; 
    10.6          ret = -ESRCH;
    10.7 -        d = find_domain_by_id( op->u.setdomainmaxmem.domain );
    10.8 +        d = find_domain_by_id( op->u.setdomainvmassist.domain );
    10.9          if ( d != NULL )
   10.10          {
   10.11              vm_assist(d, op->u.setdomainvmassist.cmd,
    11.1 --- a/xen/common/page_alloc.c	Tue Jan 18 08:28:11 2005 +0000
    11.2 +++ b/xen/common/page_alloc.c	Wed Jan 19 14:11:35 2005 +0000
    11.3 @@ -203,10 +203,8 @@ unsigned long alloc_boot_pages(unsigned 
    11.4  #define NR_ZONES    2
    11.5  
    11.6  /* Up to 2^10 pages can be allocated at once. */
    11.7 -#define MIN_ORDER  0
    11.8  #define MAX_ORDER 10
    11.9 -#define NR_ORDERS (MAX_ORDER - MIN_ORDER + 1)
   11.10 -static struct list_head heap[NR_ZONES][NR_ORDERS];
   11.11 +static struct list_head heap[NR_ZONES][MAX_ORDER+1];
   11.12  
   11.13  static unsigned long avail[NR_ZONES];
   11.14  
   11.15 @@ -220,7 +218,7 @@ void end_boot_allocator(void)
   11.16      memset(avail, 0, sizeof(avail));
   11.17  
   11.18      for ( i = 0; i < NR_ZONES; i++ )
   11.19 -        for ( j = 0; j < NR_ORDERS; j++ )
   11.20 +        for ( j = 0; j <= MAX_ORDER; j++ )
   11.21              INIT_LIST_HEAD(&heap[i][j]);
   11.22  
   11.23      /* Pages that are free now go to the domain sub-allocator. */
   11.24 @@ -236,34 +234,41 @@ void end_boot_allocator(void)
   11.25  }
   11.26  
   11.27  /* Hand the specified arbitrary page range to the specified heap zone. */
   11.28 -void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages)
   11.29 +void init_heap_pages(
   11.30 +    unsigned int zone, struct pfn_info *pg, unsigned long nr_pages)
   11.31  {
   11.32      unsigned long i;
   11.33  
   11.34 +    ASSERT(zone < NR_ZONES);
   11.35 +
   11.36      for ( i = 0; i < nr_pages; i++ )
   11.37          free_heap_pages(zone, pg+i, 0);
   11.38  }
   11.39  
   11.40  
   11.41  /* Allocate 2^@order contiguous pages. */
   11.42 -struct pfn_info *alloc_heap_pages(int zone, int order)
   11.43 +struct pfn_info *alloc_heap_pages(unsigned int zone, unsigned int order)
   11.44  {
   11.45      int i;
   11.46      struct pfn_info *pg;
   11.47  
   11.48 -    if ( unlikely(order < MIN_ORDER) || unlikely(order > MAX_ORDER) )
   11.49 +    ASSERT(zone < NR_ZONES);
   11.50 +
   11.51 +    if ( unlikely(order > MAX_ORDER) )
   11.52          return NULL;
   11.53  
   11.54      spin_lock(&heap_lock);
   11.55  
   11.56      /* Find smallest order which can satisfy the request. */
   11.57 -    for ( i = order; i < NR_ORDERS; i++ )
   11.58 +    for ( i = order; i <= MAX_ORDER; i++ )
   11.59  	if ( !list_empty(&heap[zone][i]) )
   11.60 -	    break;
   11.61 +	    goto found;
   11.62  
   11.63 -    if ( i == NR_ORDERS ) 
   11.64 -        goto no_memory;
   11.65 - 
   11.66 +    /* No suitable memory blocks. Fail the request. */
   11.67 +    spin_unlock(&heap_lock);
   11.68 +    return NULL;
   11.69 +
   11.70 + found: 
   11.71      pg = list_entry(heap[zone][i].next, struct pfn_info, list);
   11.72      list_del(&pg->list);
   11.73  
   11.74 @@ -281,18 +286,18 @@ struct pfn_info *alloc_heap_pages(int zo
   11.75      spin_unlock(&heap_lock);
   11.76  
   11.77      return pg;
   11.78 -
   11.79 - no_memory:
   11.80 -    spin_unlock(&heap_lock);
   11.81 -    return NULL;
   11.82  }
   11.83  
   11.84  
   11.85  /* Free 2^@order set of pages. */
   11.86 -void free_heap_pages(int zone, struct pfn_info *pg, int order)
   11.87 +void free_heap_pages(
   11.88 +    unsigned int zone, struct pfn_info *pg, unsigned int order)
   11.89  {
   11.90      unsigned long mask;
   11.91  
   11.92 +    ASSERT(zone < NR_ZONES);
   11.93 +    ASSERT(order <= MAX_ORDER);
   11.94 +
   11.95      spin_lock(&heap_lock);
   11.96  
   11.97      map_free(page_to_pfn(pg), 1 << order);
   11.98 @@ -393,7 +398,7 @@ void init_xenheap_pages(unsigned long ps
   11.99  }
  11.100  
  11.101  
  11.102 -unsigned long alloc_xenheap_pages(int order)
  11.103 +unsigned long alloc_xenheap_pages(unsigned int order)
  11.104  {
  11.105      unsigned long flags;
  11.106      struct pfn_info *pg;
  11.107 @@ -431,7 +436,7 @@ unsigned long alloc_xenheap_pages(int or
  11.108  }
  11.109  
  11.110  
  11.111 -void free_xenheap_pages(unsigned long p, int order)
  11.112 +void free_xenheap_pages(unsigned long p, unsigned int order)
  11.113  {
  11.114      unsigned long flags;
  11.115  
  11.116 @@ -459,7 +464,7 @@ void init_domheap_pages(unsigned long ps
  11.117  }
  11.118  
  11.119  
  11.120 -struct pfn_info *alloc_domheap_pages(struct domain *d, int order)
  11.121 +struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order)
  11.122  {
  11.123      struct pfn_info *pg;
  11.124      unsigned long mask, flushed_mask, pfn_stamp, cpu_stamp;
  11.125 @@ -535,7 +540,7 @@ struct pfn_info *alloc_domheap_pages(str
  11.126  }
  11.127  
  11.128  
  11.129 -void free_domheap_pages(struct pfn_info *pg, int order)
  11.130 +void free_domheap_pages(struct pfn_info *pg, unsigned int order)
  11.131  {
  11.132      int            i, drop_dom_ref;
  11.133      struct domain *d = pg->u.inuse.domain;
    12.1 --- a/xen/include/xen/mm.h	Tue Jan 18 08:28:11 2005 +0000
    12.2 +++ b/xen/include/xen/mm.h	Wed Jan 19 14:11:35 2005 +0000
    12.3 @@ -12,22 +12,24 @@ unsigned long alloc_boot_pages(unsigned 
    12.4  void end_boot_allocator(void);
    12.5  
    12.6  /* Generic allocator. These functions are *not* interrupt-safe. */
    12.7 -void init_heap_pages(int zone, struct pfn_info *pg, unsigned long nr_pages);
    12.8 -struct pfn_info *alloc_heap_pages(int zone, int order);
    12.9 -void free_heap_pages(int zone, struct pfn_info *pg, int order);
   12.10 +void init_heap_pages(
   12.11 +    unsigned int zone, struct pfn_info *pg, unsigned long nr_pages);
   12.12 +struct pfn_info *alloc_heap_pages(unsigned int zone, unsigned int order);
   12.13 +void free_heap_pages(
   12.14 +    unsigned int zone, struct pfn_info *pg, unsigned int order);
   12.15  void scrub_heap_pages(void);
   12.16  
   12.17  /* Xen suballocator. These functions are interrupt-safe. */
   12.18  void init_xenheap_pages(unsigned long ps, unsigned long pe);
   12.19 -unsigned long alloc_xenheap_pages(int order);
   12.20 -void free_xenheap_pages(unsigned long p, int order);
   12.21 +unsigned long alloc_xenheap_pages(unsigned int order);
   12.22 +void free_xenheap_pages(unsigned long p, unsigned int order);
   12.23  #define alloc_xenheap_page() (alloc_xenheap_pages(0))
   12.24  #define free_xenheap_page(_p) (free_xenheap_pages(_p,0))
   12.25  
   12.26  /* Domain suballocator. These functions are *not* interrupt-safe.*/
   12.27  void init_domheap_pages(unsigned long ps, unsigned long pe);
   12.28 -struct pfn_info *alloc_domheap_pages(struct domain *d, int order);
   12.29 -void free_domheap_pages(struct pfn_info *pg, int order);
   12.30 +struct pfn_info *alloc_domheap_pages(struct domain *d, unsigned int order);
   12.31 +void free_domheap_pages(struct pfn_info *pg, unsigned int order);
   12.32  unsigned long avail_domheap_pages(void);
   12.33  #define alloc_domheap_page(_d) (alloc_domheap_pages(_d,0))
   12.34  #define free_domheap_page(_p) (free_domheap_pages(_p,0))