ia64/xen-unstable

changeset 827:d0e35aa76dc3

bitkeeper revision 1.510 (3f8b2293sVxqxMv1f_A1X3GD3f08Fg)

xen_physdisk.c, domain.c, dom0_ops.c:
Various bug fixes and cleanups. Killing domains now works again.
author kaf24@scramble.cl.cam.ac.uk
date Mon Oct 13 22:09:23 2003 +0000 (2003-10-13)
parents 429f9e870989
children cf07f0fdbf52 832c781c16db
files xen/common/dom0_ops.c xen/common/domain.c xen/drivers/block/xen_physdisk.c
line diff
     1.1 --- a/xen/common/dom0_ops.c	Mon Oct 13 19:27:39 2003 +0000
     1.2 +++ b/xen/common/dom0_ops.c	Mon Oct 13 22:09:23 2003 +0000
     1.3 @@ -148,9 +148,10 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     1.4          if ( p == NULL ) 
     1.5              goto exit_create;
     1.6  
     1.7 -	if (op.u.newdomain.name[0]) {
     1.8 -            strncpy (p -> name, op.u.newdomain.name, MAX_DOMAIN_NAME);
     1.9 -            p -> name[MAX_DOMAIN_NAME - 1] = 0;
    1.10 +	if ( op.u.newdomain.name[0] )
    1.11 +        {
    1.12 +            strncpy (p->name, op.u.newdomain.name, MAX_DOMAIN_NAME);
    1.13 +            p->name[MAX_DOMAIN_NAME - 1] = 0;
    1.14  	}
    1.15  
    1.16          ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
    1.17 @@ -166,7 +167,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    1.18          
    1.19          op.u.newdomain.domain = ret;
    1.20          copy_to_user(u_dom0_op, &op, sizeof(op));
    1.21 -
    1.22 + 
    1.23      exit_create:
    1.24          spin_unlock_irq(&create_dom_lock);
    1.25      }
     2.1 --- a/xen/common/domain.c	Mon Oct 13 19:27:39 2003 +0000
     2.2 +++ b/xen/common/domain.c	Mon Oct 13 22:09:23 2003 +0000
     2.3 @@ -91,7 +91,7 @@ struct task_struct *do_newdomain(unsigne
     2.4      task_hash[TASK_HASH(dom_id)] = p;
     2.5      write_unlock_irqrestore(&tasklist_lock, flags);
     2.6  
     2.7 -    return(p);
     2.8 +    return p;
     2.9  }
    2.10  
    2.11  
    2.12 @@ -128,6 +128,8 @@ void kill_domain_with_errmsg(const char 
    2.13  void __kill_domain(struct task_struct *p)
    2.14  {
    2.15      int i;
    2.16 +    struct task_struct **pp;
    2.17 +    unsigned long flags;
    2.18  
    2.19      if ( p->domain == 0 )
    2.20      {
    2.21 @@ -148,6 +150,17 @@ void __kill_domain(struct task_struct *p
    2.22      for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
    2.23          unlink_net_vif(p->net_vif_list[i]);
    2.24  
    2.25 +    /*
    2.26 +     * Note this means that find_domain_by_id may fail, even when the caller
    2.27 +     * holds a reference to the domain being queried. Take care!
    2.28 +     */
    2.29 +    write_lock_irqsave(&tasklist_lock, flags);
    2.30 +    REMOVE_LINKS(p);
    2.31 +    pp = &task_hash[TASK_HASH(p->domain)];
    2.32 +    while ( *pp != p ) *pp = (*pp)->next_hash;
    2.33 +    *pp = p->next_hash;
    2.34 +    write_unlock_irqrestore(&tasklist_lock, flags);
    2.35 +
    2.36      if ( p == current )
    2.37      {
    2.38          __enter_scheduler();
    2.39 @@ -289,21 +302,11 @@ void free_all_dom_mem(struct task_struct
    2.40  /* Release resources belonging to task @p. */
    2.41  void release_task(struct task_struct *p)
    2.42  {
    2.43 -    struct task_struct **pp;
    2.44 -    unsigned long flags;
    2.45 -
    2.46      ASSERT(p->state == TASK_DYING);
    2.47      ASSERT(!p->has_cpu);
    2.48  
    2.49      printk("Releasing task %d\n", p->domain);
    2.50  
    2.51 -    write_lock_irqsave(&tasklist_lock, flags);
    2.52 -    REMOVE_LINKS(p);
    2.53 -    pp = &task_hash[TASK_HASH(p->domain)];
    2.54 -    while ( *pp != p ) *pp = (*pp)->next_hash;
    2.55 -    *pp = p->next_hash;
    2.56 -    write_unlock_irqrestore(&tasklist_lock, flags);
    2.57 -
    2.58      /*
    2.59       * This frees up blkdev rings. Totally safe since blkdev ref counting
    2.60       * actually uses the task_struct refcnt.
    2.61 @@ -318,7 +321,8 @@ void release_task(struct task_struct *p)
    2.62      UNSHARE_PFN(virt_to_page(p->shared_info));
    2.63      free_page((unsigned long)p->shared_info);
    2.64      free_all_dom_mem(p);
    2.65 -    free_pages((unsigned long)p, 1);
    2.66 +
    2.67 +    kmem_cache_free(task_struct_cachep, p);
    2.68  }
    2.69  
    2.70  
     3.1 --- a/xen/drivers/block/xen_physdisk.c	Mon Oct 13 19:27:39 2003 +0000
     3.2 +++ b/xen/drivers/block/xen_physdisk.c	Mon Oct 13 22:09:23 2003 +0000
     3.3 @@ -23,7 +23,6 @@
     3.4     and we fake the logical view on top of that. */
     3.5  struct physdisk_ace {
     3.6      struct list_head list;
     3.7 -
     3.8      unsigned short device;
     3.9      unsigned short partition;
    3.10      unsigned long start_sect;
    3.11 @@ -40,30 +39,23 @@ static struct physdisk_ace *find_ace(con
    3.12      struct list_head *cur_ace_head;
    3.13      struct physdisk_ace *cur_ace;
    3.14  
    3.15 -    list_for_each(cur_ace_head, &p->physdisk_aces) {
    3.16 +    list_for_each(cur_ace_head, &p->physdisk_aces)
    3.17 +    {
    3.18  	cur_ace = list_entry(cur_ace_head, struct physdisk_ace, list);
    3.19  	DPRINTK("Is [%lx, %lx) good for %lx?\n",
    3.20  		cur_ace->start_sect,
    3.21  		cur_ace->start_sect + cur_ace->n_sectors, sect);
    3.22 -	if (sect >= cur_ace->start_sect
    3.23 -	    && sect < cur_ace->start_sect + cur_ace->n_sectors
    3.24 -	    && dev == cur_ace->device
    3.25 -	    && ((operation == READ && (cur_ace->mode & PHYSDISK_MODE_R))
    3.26 -		|| (operation == WRITE
    3.27 -		    && (cur_ace->mode & PHYSDISK_MODE_W)))) {
    3.28 -	    DPRINTK("Yes.\n");
    3.29 +	if ( (sect >= cur_ace->start_sect) &&
    3.30 +	     (sect < (cur_ace->start_sect + cur_ace->n_sectors)) &&
    3.31 +             (dev == cur_ace->device) &&
    3.32 +             (((operation == READ) && (cur_ace->mode & PHYSDISK_MODE_R)) ||
    3.33 +              ((operation == WRITE) && (cur_ace->mode & PHYSDISK_MODE_W))) )
    3.34  	    return cur_ace;
    3.35 -	} else {
    3.36 -	    DPRINTK("No.\n");
    3.37 -	}
    3.38      }
    3.39      return NULL;
    3.40  }
    3.41  
    3.42  /* Hold the lock on entry, it remains held on exit. */
    3.43 -/* XXX we call kmalloc and kfree with GFP_KERNEL and a spinlock held
    3.44 -   in here.  That wouldn't be allowed under Linux, but, from reading
    3.45 -   the source, it seems to be okay under Xen... */
    3.46  static void xen_physdisk_revoke_access(unsigned short dev,
    3.47  				       unsigned long start_sect,
    3.48  				       unsigned long n_sectors,
    3.49 @@ -77,31 +69,41 @@ static void xen_physdisk_revoke_access(u
    3.50      unsigned long kill_zone_end, ace_end;
    3.51  
    3.52      kill_zone_end = start_sect + n_sectors;
    3.53 -    list_for_each(cur_ace_head, &p->physdisk_aces) {
    3.54 +    list_for_each(cur_ace_head, &p->physdisk_aces) 
    3.55 +    {
    3.56  	cur_ace = list_entry(cur_ace_head, struct physdisk_ace, list);
    3.57  	ace_end = cur_ace->start_sect + cur_ace->n_sectors;
    3.58 -	if (cur_ace->start_sect >= kill_zone_end ||
    3.59 -	    ace_end <= start_sect || cur_ace->device != dev)
    3.60 +	if ( (cur_ace->start_sect >= kill_zone_end) ||
    3.61 +             (ace_end <= start_sect) || 
    3.62 +             (cur_ace->device != dev) )
    3.63  	    continue;
    3.64  
    3.65  	DPRINTK("Killing ace [%lx, %lx) against kill zone [%lx, %lx)\n",
    3.66  		cur_ace->start_sect, ace_end, start_sect, kill_zone_end);
    3.67  
    3.68 -	if (cur_ace->start_sect >= start_sect && ace_end <= kill_zone_end) {
    3.69 +	if ( (cur_ace->start_sect >= start_sect) && 
    3.70 +             (ace_end <= kill_zone_end) )
    3.71 +        {
    3.72  	    /* ace entirely within kill zone -> kill it */
    3.73  	    list_del(cur_ace_head);
    3.74  	    cur_ace_head = cur_ace_head->prev;
    3.75  	    kfree(cur_ace);
    3.76 -	} else if (ace_end <= kill_zone_end) {
    3.77 +	} 
    3.78 +        else if ( ace_end <= kill_zone_end )
    3.79 +        {
    3.80  	    /* ace start before kill start, ace end in kill zone, 
    3.81  	       move ace end. */
    3.82  	    cur_ace->n_sectors = start_sect - cur_ace->start_sect;
    3.83 -	} else if (cur_ace->start_sect >= start_sect) {
    3.84 +	} 
    3.85 +        else if ( cur_ace->start_sect >= start_sect )
    3.86 +        {
    3.87  	    /* ace start after kill start, ace end outside kill zone,
    3.88  	       move ace start. */
    3.89  	    cur_ace->start_sect = kill_zone_end;
    3.90  	    cur_ace->n_sectors = ace_end - cur_ace->start_sect;
    3.91 -	} else {
    3.92 +	} 
    3.93 +        else 
    3.94 +        {
    3.95  	    /* The fun one: the ace entirely includes the kill zone. */
    3.96  	    /* Cut the current ace down to just the bit before the kzone,
    3.97  	       create a new ace for the bit just after it. */
    3.98 @@ -132,7 +134,8 @@ static int xen_physdisk_grant_access(uns
    3.99         and we try to grant write access, or vice versa. */
   3.100      xen_physdisk_revoke_access(dev, start_sect, n_sectors, p);
   3.101  
   3.102 -    if (mode) {
   3.103 +    if ( mode ) 
   3.104 +    {
   3.105  	cur_ace = kmalloc(sizeof(*cur_ace), GFP_KERNEL);
   3.106  	cur_ace->device = dev;
   3.107  	cur_ace->start_sect = start_sect;
   3.108 @@ -155,9 +158,11 @@ static void xen_physdisk_probe_access(ph
   3.109      int x = 0;
   3.110  
   3.111      n_aces = 0;
   3.112 -    list_for_each(cur_ace_head, &p->physdisk_aces) {
   3.113 +    list_for_each(cur_ace_head, &p->physdisk_aces) 
   3.114 +    {
   3.115  	x++;
   3.116 -	if (x >= buf->start_ind) {
   3.117 +	if ( x >= buf->start_ind ) 
   3.118 +        {
   3.119  	    cur_ace = list_entry(cur_ace_head, struct physdisk_ace, list);
   3.120  	    buf->entries[n_aces].device = cur_ace->device;
   3.121  	    buf->entries[n_aces].partition = cur_ace->partition;
   3.122 @@ -172,20 +177,18 @@ static void xen_physdisk_probe_access(ph
   3.123  
   3.124  int xen_physdisk_grant(xp_disk_t * xpd_in)
   3.125  {
   3.126 -    struct task_struct *p;
   3.127 +    struct task_struct *p = current;
   3.128      xp_disk_t *xpd = map_domain_mem(virt_to_phys(xpd_in));
   3.129      int res;
   3.130  
   3.131 -    p = current;
   3.132 -    DPRINTK("Have current.\n");
   3.133 -    DPRINTK("Target domain %x\n", xpd->domain);
   3.134 -
   3.135      p = find_domain_by_id(xpd->domain);
   3.136 -    if (p == NULL) {
   3.137 +    if ( p == NULL )
   3.138 +    {
   3.139  	DPRINTK("Bad domain!\n");
   3.140  	res = 1;
   3.141  	goto out;
   3.142      }
   3.143 +
   3.144      spin_lock(&p->physdev_lock);
   3.145      res = xen_physdisk_grant_access(xpd->device,
   3.146  				    xpd->partition,
   3.147 @@ -206,14 +209,16 @@ int xen_physdisk_probe(struct task_struc
   3.148      physdisk_probebuf_t *buf = map_domain_mem(virt_to_phys(buf_in));
   3.149      int res;
   3.150  
   3.151 -    if (requesting_domain->domain != 0 &&
   3.152 -	requesting_domain->domain != buf->domain) {
   3.153 +    if ( (requesting_domain->domain != 0) &&
   3.154 +	 (requesting_domain->domain != buf->domain) )
   3.155 +    {
   3.156  	res = 1;
   3.157  	goto out;
   3.158      }
   3.159  
   3.160      p = find_domain_by_id(buf->domain);
   3.161 -    if (p == NULL) {
   3.162 +    if ( p == NULL )
   3.163 +    {
   3.164  	res = 1;
   3.165  	goto out;
   3.166      }
   3.167 @@ -239,17 +244,16 @@ int xen_physdisk_access_okay(phys_seg_t 
   3.168  	("Checking access for domain %d, start sect 0x%lx, length 0x%x.\n",
   3.169  	 p->domain, pseg->sector_number, pseg->nr_sects);
   3.170  
   3.171 -    for (sect = pseg->sector_number;
   3.172 -	 sect < pseg->sector_number + pseg->nr_sects;) {
   3.173 +    for ( sect = pseg->sector_number;
   3.174 +	  sect < pseg->sector_number + pseg->nr_sects; ) 
   3.175 +    {
   3.176  	/* XXX this would be a lot faster if the aces were sorted on start
   3.177  	   address.  Also in revoke_access. */
   3.178  	spin_lock(&p->physdev_lock);
   3.179  	cur_ace = find_ace(p, pseg->dev, sect, operation);
   3.180  	spin_unlock(&p->physdev_lock);
   3.181 -	if (!cur_ace) {
   3.182 -	    /* Default closed. */
   3.183 +	if ( cur_ace == NULL )
   3.184  	    return 0;
   3.185 -	}
   3.186  	sect +=
   3.187  	    MAX(cur_ace->n_sectors,
   3.188  		pseg->nr_sects + pseg->sector_number - sect);
   3.189 @@ -262,10 +266,10 @@ void destroy_physdisk_aces(struct task_s
   3.190      struct list_head *cur_ace_head, *next_head;
   3.191      struct physdisk_ace *cur_ace;
   3.192  
   3.193 -    spin_lock(&p->physdev_lock);	/* We never release this again. */
   3.194 -
   3.195 -    for (cur_ace_head = p->physdisk_aces.next;
   3.196 -	 cur_ace_head != &p->physdisk_aces; cur_ace_head = next_head) {
   3.197 +    for ( cur_ace_head = p->physdisk_aces.next;
   3.198 +          cur_ace_head != &p->physdisk_aces; 
   3.199 +          cur_ace_head = next_head )
   3.200 +    {
   3.201  	cur_ace = list_entry(cur_ace_head, struct physdisk_ace, list);
   3.202  	next_head = cur_ace_head->next;
   3.203  	kfree(cur_ace);