ia64/xen-unstable

changeset 126:25df5d63ff28

bitkeeper revision 1.22.2.3 (3e42f257DQUNW5mSYvOQT0Fq2ArFEw)

sched.h, memory.c, domain.c, dom0_ops.c, ioremap.c, entry.S:
Fix bug in domain-memory allocation. Per-domain page lists now have a proper Linux-style 'list_head'.
author kaf24@labyrinth.cl.cam.ac.uk
date Thu Feb 06 23:40:07 2003 +0000 (2003-02-06)
parents b591e70eec1d
children 88c1cf85fc8f
files xen-2.4.16/arch/i386/entry.S xen-2.4.16/arch/i386/ioremap.c xen-2.4.16/common/dom0_ops.c xen-2.4.16/common/domain.c xen-2.4.16/common/memory.c xen-2.4.16/include/xeno/sched.h
line diff
     1.1 --- a/xen-2.4.16/arch/i386/entry.S	Thu Feb 06 16:20:54 2003 +0000
     1.2 +++ b/xen-2.4.16/arch/i386/entry.S	Thu Feb 06 23:40:07 2003 +0000
     1.3 @@ -102,7 +102,7 @@ PROCESSOR       =  0
     1.4  STATE           =  4
     1.5  HYP_EVENTS      =  8
     1.6  DOMAIN          = 12        
     1.7 -SHARED_INFO     = 24
     1.8 +SHARED_INFO     = 16
     1.9  
    1.10  /* Offsets in shared_info_t */
    1.11  EVENTS          =  0
     2.1 --- a/xen-2.4.16/arch/i386/ioremap.c	Thu Feb 06 16:20:54 2003 +0000
     2.2 +++ b/xen-2.4.16/arch/i386/ioremap.c	Thu Feb 06 23:40:07 2003 +0000
     2.3 @@ -15,8 +15,8 @@
     2.4  
     2.5  static unsigned long remap_base = 0;
     2.6  
     2.7 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
     2.8 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY)
     2.9 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    2.10 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY)
    2.11  
    2.12  #define PAGE_ALIGN(addr)    (((addr)+PAGE_SIZE-1)&PAGE_MASK)
    2.13  
     3.1 --- a/xen-2.4.16/common/dom0_ops.c	Thu Feb 06 16:20:54 2003 +0000
     3.2 +++ b/xen-2.4.16/common/dom0_ops.c	Thu Feb 06 23:40:07 2003 +0000
     3.3 @@ -32,26 +32,26 @@ static unsigned int get_domnr(void)
     3.4  
     3.5  static void build_page_list(struct task_struct *p)
     3.6  {
     3.7 -    unsigned long * list;
     3.8 +    unsigned long *list;
     3.9      unsigned long curr;
    3.10 -    unsigned long page;
    3.11      struct list_head *list_ent;
    3.12  
    3.13 -    list = (unsigned long *)map_domain_mem(p->pg_head << PAGE_SHIFT);
    3.14 -    curr = page = p->pg_head;
    3.15 -    do {
    3.16 -        *list++ = page;
    3.17 -        list_ent = frame_table[page].list.next;
    3.18 -        page = list_entry(list_ent, struct pfn_info, list) - frame_table;
    3.19 -        if( !((unsigned long)list & (PAGE_SIZE-1)) )
    3.20 +    curr = list_entry(p->pg_head.next, struct pfn_info, list) - frame_table;
    3.21 +    list = (unsigned long *)map_domain_mem(curr << PAGE_SHIFT);
    3.22 +
    3.23 +    list_for_each(list_ent, &p->pg_head)
    3.24 +    {
    3.25 +        *list++ = list_entry(list_ent, struct pfn_info, list) - frame_table;
    3.26 +
    3.27 +        if( ((unsigned long)list & ~PAGE_MASK) == 0 )
    3.28          {
    3.29 -            list_ent = frame_table[curr].list.next;
    3.30 -            curr = list_entry(list_ent, struct pfn_info, list) - frame_table;
    3.31 +            struct list_head *ent = frame_table[curr].list.next;
    3.32 +            curr = list_entry(ent, struct pfn_info, list) - frame_table;
    3.33              unmap_domain_mem(list-1);
    3.34              list = (unsigned long *)map_domain_mem(curr << PAGE_SHIFT);
    3.35          }
    3.36      }
    3.37 -    while ( page != p->pg_head );
    3.38 +
    3.39      unmap_domain_mem(list);
    3.40  }
    3.41      
    3.42 @@ -97,37 +97,20 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    3.43          pro = (pro+1) % smp_num_cpus;
    3.44          p->processor = pro;
    3.45  
    3.46 -        /* if we are not booting dom 0 than only mem 
    3.47 -         * needs to be allocated
    3.48 -         */
    3.49 -        if(dom != 0){
    3.50 +        if ( dom == 0 ) BUG();
    3.51  
    3.52 -            if(alloc_new_dom_mem(p, op.u.newdomain.memory_kb) != 0){
    3.53 -                ret = -1;
    3.54 -                break;
    3.55 -            }
    3.56 -            build_page_list(p);
    3.57 -            
    3.58 -            ret = p->domain;
    3.59 +        ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
    3.60 +        if ( ret != 0 ) break;
    3.61  
    3.62 -            op.u.newdomain.domain = ret;
    3.63 -            op.u.newdomain.pg_head = p->pg_head;
    3.64 -            copy_to_user(u_dom0_op, &op, sizeof(op));
    3.65 -
    3.66 -            break;
    3.67 -        }
    3.68 -
    3.69 -        /* executed only in case of domain 0 */
    3.70 -        ret = setup_guestos(p, &op.u.newdomain);    /* Load guest OS into @p */
    3.71 -        if ( ret != 0 ) 
    3.72 -        {
    3.73 -            p->state = TASK_DYING;
    3.74 -            release_task(p);
    3.75 -            break;
    3.76 -        }
    3.77 -        wake_up(p);          /* Put @p on runqueue */
    3.78 -        reschedule(p);       /* Force a scheduling decision on @p's CPU */
    3.79 +        build_page_list(p);
    3.80 +        
    3.81          ret = p->domain;
    3.82 +        
    3.83 +        op.u.newdomain.domain = ret;
    3.84 +        op.u.newdomain.pg_head = 
    3.85 +            list_entry(p->pg_head.next, struct pfn_info, list) -
    3.86 +            frame_table;
    3.87 +        copy_to_user(u_dom0_op, &op, sizeof(op));
    3.88      }
    3.89      break;
    3.90  
     4.1 --- a/xen-2.4.16/common/domain.c	Thu Feb 06 16:20:54 2003 +0000
     4.2 +++ b/xen-2.4.16/common/domain.c	Thu Feb 06 23:40:07 2003 +0000
     4.3 @@ -14,8 +14,8 @@
     4.4  #include <asm/msr.h>
     4.5  #include <xeno/multiboot.h>
     4.6  
     4.7 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
     4.8 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
     4.9 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
    4.10 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
    4.11  
    4.12  extern int nr_mods;
    4.13  extern module_t *mod;
    4.14 @@ -69,7 +69,8 @@ struct task_struct *do_newdomain(void)
    4.15       */
    4.16      p->blk_ring_base = (blk_ring_t *)(p->shared_info + 1);
    4.17      p->net_ring_base = (net_ring_t *)(p->blk_ring_base + 1);
    4.18 -    p->pg_head = p->tot_pages = 0;
    4.19 +    INIT_LIST_HEAD(&p->pg_head);
    4.20 +    p->tot_pages = 0;
    4.21      write_lock_irqsave(&tasklist_lock, flags);
    4.22      SET_LINKS(p);
    4.23      write_unlock_irqrestore(&tasklist_lock, flags);
    4.24 @@ -243,6 +244,8 @@ long kill_other_domain(unsigned int dom)
    4.25  /* Release resources belonging to task @p. */
    4.26  void release_task(struct task_struct *p)
    4.27  {
    4.28 +    struct list_head *list_ent, *tmp;
    4.29 +
    4.30      ASSERT(!__task_on_runqueue(p));
    4.31      ASSERT(p->state == TASK_DYING);
    4.32      ASSERT(!p->has_cpu);
    4.33 @@ -261,17 +264,15 @@ void release_task(struct task_struct *p)
    4.34      }
    4.35      if ( p->mm.perdomain_pt ) free_page((unsigned long)p->mm.perdomain_pt);
    4.36      free_page((unsigned long)p->shared_info);
    4.37 -    if ( p->tot_pages != 0 )
    4.38 +
    4.39 +    list_for_each_safe(list_ent, tmp, &p->pg_head)
    4.40      {
    4.41 -        /* Splice domain's pages into the free list. */
    4.42 -        struct list_head *first = &frame_table[p->pg_head].list;
    4.43 -        struct list_head *last  = first->prev;
    4.44 -        free_list.next->prev = last;
    4.45 -        last->next = free_list.next;
    4.46 -        free_list.next = first;
    4.47 -        first->prev = &free_list;            
    4.48 -        free_pfns += p->tot_pages;
    4.49 +        struct pfn_info *pf = list_entry(list_ent, struct pfn_info, list);
    4.50 +        pf->type_count = pf->tot_count = pf->flags = 0;
    4.51 +        list_del(list_ent);
    4.52 +        list_add(list_ent, &free_list);
    4.53      }
    4.54 +
    4.55      free_task_struct(p);
    4.56  }
    4.57  
    4.58 @@ -350,7 +351,7 @@ asmlinkage void schedule(void)
    4.59  unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes)
    4.60  {
    4.61      struct list_head *temp;
    4.62 -    struct pfn_info *pf, *pf_head;
    4.63 +    struct pfn_info *pf;
    4.64      unsigned int alloc_pfns;
    4.65      unsigned int req_pages;
    4.66  
    4.67 @@ -358,33 +359,18 @@ unsigned int alloc_new_dom_mem(struct ta
    4.68      req_pages = kbytes >> (PAGE_SHIFT - 10);
    4.69  
    4.70      /* is there enough mem to serve the request? */   
    4.71 -    if(req_pages > free_pfns)
    4.72 -        return -1;
    4.73 +    if ( req_pages > free_pfns ) return -1;
    4.74      
    4.75      /* allocate pages and build a thread through frame_table */
    4.76      temp = free_list.next;
    4.77 -
    4.78 -    /* allocate first page */
    4.79 -    pf = pf_head = list_entry(temp, struct pfn_info, list);
    4.80 -    pf->flags |= p->domain;
    4.81 -    temp = temp->next;
    4.82 -    list_del(&pf->list);
    4.83 -    INIT_LIST_HEAD(&pf->list);
    4.84 -    p->pg_head = pf - frame_table;
    4.85 -    pf->type_count = pf->tot_count = 0;
    4.86 -    free_pfns--;
    4.87 -
    4.88 -    /* allocate the rest */
    4.89 -    for ( alloc_pfns = req_pages - 1; alloc_pfns; alloc_pfns-- )
    4.90 +    for ( alloc_pfns = 0; alloc_pfns < req_pages; alloc_pfns++ )
    4.91      {
    4.92          pf = list_entry(temp, struct pfn_info, list);
    4.93          pf->flags |= p->domain;
    4.94 +        pf->type_count = pf->tot_count = 0;
    4.95          temp = temp->next;
    4.96          list_del(&pf->list);
    4.97 -
    4.98 -        list_add_tail(&pf->list, &pf_head->list);
    4.99 -        pf->type_count = pf->tot_count = 0;
   4.100 -
   4.101 +        list_add_tail(&pf->list, &p->pg_head);
   4.102          free_pfns--;
   4.103      }
   4.104      
   4.105 @@ -532,11 +518,12 @@ int final_setup_guestos(struct task_stru
   4.106  static unsigned long alloc_page_from_domain(unsigned long * cur_addr, 
   4.107      unsigned long * index)
   4.108  {
   4.109 -    struct list_head *ent = frame_table[*cur_addr >> PAGE_SHIFT].list.prev;
   4.110 +    unsigned long ret = *cur_addr;
   4.111 +    struct list_head *ent = frame_table[ret >> PAGE_SHIFT].list.prev;
   4.112      *cur_addr = list_entry(ent, struct pfn_info, list) - frame_table;
   4.113      *cur_addr <<= PAGE_SHIFT;
   4.114      (*index)--;    
   4.115 -    return *cur_addr;
   4.116 +    return ret;
   4.117  }
   4.118  
   4.119  /* setup_guestos is used for building dom0 solely. other domains are built in
   4.120 @@ -578,7 +565,9 @@ int setup_guestos(struct task_struct *p,
   4.121      }
   4.122  
   4.123      if ( alloc_new_dom_mem(p, params->memory_kb) ) return -ENOMEM;
   4.124 -    alloc_address = p->pg_head << PAGE_SHIFT;
   4.125 +    alloc_address = list_entry(p->pg_head.prev, struct pfn_info, list) -
   4.126 +        frame_table;
   4.127 +    alloc_address <<= PAGE_SHIFT;
   4.128      alloc_index = p->tot_pages;
   4.129  
   4.130      if ( (mod[nr_mods-1].mod_end-mod[0].mod_start) > 
   4.131 @@ -615,7 +604,9 @@ int setup_guestos(struct task_struct *p,
   4.132       */
   4.133  
   4.134      l2tab += l2_table_offset(virt_load_address);
   4.135 -    cur_address = p->pg_head << PAGE_SHIFT;
   4.136 +    cur_address = list_entry(p->pg_head.next, struct pfn_info, list) -
   4.137 +        frame_table;
   4.138 +    cur_address <<= PAGE_SHIFT;
   4.139      for ( count = 0; count < p->tot_pages + 1; count++ )
   4.140      {
   4.141          if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
   4.142 @@ -647,7 +638,9 @@ int setup_guestos(struct task_struct *p,
   4.143      unmap_domain_mem(l1start);
   4.144  
   4.145      /* pages that are part of page tables must be read only */
   4.146 -    cur_address = p->pg_head << PAGE_SHIFT;
   4.147 +    cur_address = list_entry(p->pg_head.next, struct pfn_info, list) -
   4.148 +        frame_table;
   4.149 +    cur_address <<= PAGE_SHIFT;
   4.150      for ( count = 0; count < alloc_index; count++ ) 
   4.151      {
   4.152          list_ent = frame_table[cur_address >> PAGE_SHIFT].list.next;
     5.1 --- a/xen-2.4.16/common/memory.c	Thu Feb 06 16:20:54 2003 +0000
     5.2 +++ b/xen-2.4.16/common/memory.c	Thu Feb 06 23:40:07 2003 +0000
     5.3 @@ -175,7 +175,7 @@
     5.4  #include <asm/uaccess.h>
     5.5  #include <asm/domain_page.h>
     5.6  
     5.7 -#if 1
     5.8 +#if 0
     5.9  #define MEM_LOG(_f, _a...) printk("DOM%d: (file=memory.c, line=%d) " _f "\n", current->domain, __LINE__, ## _a )
    5.10  #else
    5.11  #define MEM_LOG(_f, _a...) ((void)0)
     6.1 --- a/xen-2.4.16/include/xeno/sched.h	Thu Feb 06 16:20:54 2003 +0000
     6.2 +++ b/xen-2.4.16/include/xeno/sched.h	Thu Feb 06 23:40:07 2003 +0000
     6.3 @@ -63,17 +63,12 @@ struct task_struct {
     6.4      int state, hyp_events;
     6.5      unsigned int domain;
     6.6  
     6.7 -    /* index into frame_table threading pages belonging to this
     6.8 -     * domain together. these are placed at the top of the structure
     6.9 -     * to avoid nasty padding for various kernel structs when using
    6.10 -     * task_struct in user space
    6.11 -     */
    6.12 -    unsigned long pg_head;
    6.13 -    unsigned int tot_pages;
    6.14 -
    6.15      /* An unsafe pointer into a shared data area. */
    6.16      shared_info_t *shared_info;
    6.17      
    6.18 +    struct list_head pg_head;
    6.19 +    unsigned int tot_pages;
    6.20 +
    6.21      /* Pointer to this guest's virtual interfaces. */
    6.22      /* network */
    6.23      net_ring_t *net_ring_base;