ia64/xen-unstable

changeset 2063:f5ce0f8cd1b0

bitkeeper revision 1.1131.1.1 (410fcd36BPCOqi_xOwMe3B30qkp45A)

Cleanup vbd_lock locking. Fixes scheduler lockup when trying to create a
vbd with a non-existant device.
author cl349@freefall.cl.cam.ac.uk
date Tue Aug 03 17:36:54 2004 +0000 (2004-08-03)
parents 5dc17e68374c
children ef4ec427c032 f6353cfb77fa
files linux-2.6.7-xen-sparse/drivers/xen/blkback/vbd.c
line diff
     1.1 --- a/linux-2.6.7-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 03 14:03:58 2004 +0000
     1.2 +++ b/linux-2.6.7-xen-sparse/drivers/xen/blkback/vbd.c	Tue Aug 03 17:36:54 2004 +0000
     1.3 @@ -10,6 +10,11 @@
     1.4  
     1.5  static dev_t vbd_map_devnum(blkif_pdev_t);
     1.6  
     1.7 +/* vbd_lock: protects updates to the rb_tree against concurrent
     1.8 + * lookups in vbd_translate.  All other lookups are implicitly
     1.9 + * protected because the only caller (the control message dispatch
    1.10 + * routine) serializes the calls. */
    1.11 +
    1.12  void vbd_create(blkif_be_vbd_create_t *create) 
    1.13  {
    1.14      vbd_t       *vbd; 
    1.15 @@ -26,8 +31,6 @@ void vbd_create(blkif_be_vbd_create_t *c
    1.16          return;
    1.17      }
    1.18  
    1.19 -    spin_lock(&blkif->vbd_lock);
    1.20 -
    1.21      rb_p = &blkif->vbd_rb.rb_node;
    1.22      while ( *rb_p != NULL )
    1.23      {
    1.24 @@ -45,7 +48,7 @@ void vbd_create(blkif_be_vbd_create_t *c
    1.25          {
    1.26              PRINTK("vbd_create attempted for already existing vbd\n");
    1.27              create->status = BLKIF_BE_STATUS_VBD_EXISTS;
    1.28 -            goto out;
    1.29 +            return;
    1.30          }
    1.31      }
    1.32  
    1.33 @@ -53,7 +56,7 @@ void vbd_create(blkif_be_vbd_create_t *c
    1.34      {
    1.35          PRINTK("vbd_create: out of memory\n");
    1.36          create->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    1.37 -        goto out;
    1.38 +        return;
    1.39      }
    1.40  
    1.41      vbd->vdevice  = vdevice; 
    1.42 @@ -61,15 +64,14 @@ void vbd_create(blkif_be_vbd_create_t *c
    1.43      vbd->type     = VDISK_TYPE_DISK | VDISK_FLAG_VIRT;
    1.44      vbd->extents  = NULL; 
    1.45  
    1.46 +    spin_lock(&blkif->vbd_lock);
    1.47      rb_link_node(&vbd->rb, rb_parent, rb_p);
    1.48      rb_insert_color(&vbd->rb, &blkif->vbd_rb);
    1.49 +    spin_unlock(&blkif->vbd_lock);
    1.50  
    1.51      DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
    1.52              vdevice, create->domid);
    1.53      create->status = BLKIF_BE_STATUS_OKAY;
    1.54 -
    1.55 - out:
    1.56 -    spin_unlock(&blkif->vbd_lock);
    1.57  }
    1.58  
    1.59  
    1.60 @@ -93,8 +95,6 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
    1.61          return;
    1.62      }
    1.63  
    1.64 -    spin_lock(&blkif->vbd_lock);
    1.65 -
    1.66      rb = blkif->vbd_rb.rb_node;
    1.67      while ( rb != NULL )
    1.68      {
    1.69 @@ -111,54 +111,52 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
    1.70      {
    1.71          PRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n");
    1.72          grow->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
    1.73 -        goto out;
    1.74 +        return;
    1.75      } 
    1.76  
    1.77 +    if ( grow->extent.sector_start > 0 )
    1.78 +    {
    1.79 +        PRINTK("vbd_grow: device %08x start not zero!\n", grow->extent.device);
    1.80 +	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
    1.81 +	return;
    1.82 +    }
    1.83 +
    1.84      if ( unlikely((x = kmalloc(sizeof(blkif_extent_le_t), 
    1.85                                 GFP_KERNEL)) == NULL) )
    1.86      {
    1.87          PRINTK("vbd_grow: out of memory\n");
    1.88          grow->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
    1.89 -        goto out;
    1.90 +        return;
    1.91      }
    1.92  
    1.93      x->extent.device        = grow->extent.device;
    1.94 -    /* XXXcl see comments at top of open_by_devnum */
    1.95 +    x->extent.sector_start  = grow->extent.sector_start;
    1.96 +    x->extent.sector_length = grow->extent.sector_length;
    1.97 +    x->next                 = (blkif_extent_le_t *)NULL;
    1.98 +
    1.99  #if 01
   1.100 -#ifdef DONT_BLKDEV_GET
   1.101 -    x->bdev = bdget(vbd_map_devnum(x->extent.device));
   1.102 -#else
   1.103 +    /* XXXcl see comments at top of open_by_devnum */
   1.104      x->bdev = open_by_devnum(vbd_map_devnum(x->extent.device),
   1.105  			     vbd->readonly ? FMODE_READ : FMODE_WRITE);
   1.106 -#endif
   1.107 -    if (x->bdev == NULL) {
   1.108 +    if (IS_ERR(x->bdev)) {
   1.109  	PRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   1.110  	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   1.111  	goto out;
   1.112      }
   1.113 -#endif
   1.114      /* XXXcl maybe bd_claim? */
   1.115 -    x->extent.sector_start  = grow->extent.sector_start;
   1.116 -    x->extent.sector_length = grow->extent.sector_length;
   1.117 -    x->next                 = (blkif_extent_le_t *)NULL;
   1.118  
   1.119      if( x->bdev->bd_disk == NULL || x->bdev->bd_part == NULL )
   1.120      {
   1.121          PRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
   1.122  	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   1.123 +	blkdev_put(x->bdev);
   1.124  	goto out;
   1.125      }
   1.126 -    
   1.127 +#endif
   1.128 +   
   1.129      /* get size in sectors */
   1.130      sz = x->bdev->bd_part->nr_sects;
   1.131  
   1.132 -    if ( x->extent.sector_start > 0 )
   1.133 -    {
   1.134 -        PRINTK("vbd_grow: device %08x start not zero!\n", x->extent.device);
   1.135 -	grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   1.136 -	goto out;
   1.137 -    }
   1.138 -
   1.139      /*
   1.140       * NB. This test assumes sector_start == 0, which is always the case
   1.141       * in Xen 1.3. In fact the whole grow/shrink interface could do with
   1.142 @@ -179,9 +177,10 @@ void vbd_grow(blkif_be_vbd_grow_t *grow)
   1.143              vdevice, grow->domid);
   1.144      
   1.145      grow->status = BLKIF_BE_STATUS_OKAY;
   1.146 +    return;
   1.147  
   1.148   out:
   1.149 -    spin_unlock(&blkif->vbd_lock);
   1.150 +    kfree(x);
   1.151  }
   1.152  
   1.153  
   1.154 @@ -202,8 +201,6 @@ void vbd_shrink(blkif_be_vbd_shrink_t *s
   1.155          return;
   1.156      }
   1.157  
   1.158 -    spin_lock(&blkif->vbd_lock);
   1.159 -
   1.160      rb = blkif->vbd_rb.rb_node;
   1.161      while ( rb != NULL )
   1.162      {
   1.163 @@ -219,13 +216,13 @@ void vbd_shrink(blkif_be_vbd_shrink_t *s
   1.164      if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
   1.165      {
   1.166          shrink->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   1.167 -        goto out;
   1.168 +	return;
   1.169      }
   1.170  
   1.171      if ( unlikely(vbd->extents == NULL) )
   1.172      {
   1.173          shrink->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
   1.174 -        goto out;
   1.175 +	return;
   1.176      }
   1.177  
   1.178      /* Find the last extent. We now know that there is at least one. */
   1.179 @@ -235,16 +232,10 @@ void vbd_shrink(blkif_be_vbd_shrink_t *s
   1.180      x   = *px;
   1.181      *px = x->next;
   1.182  
   1.183 -#ifndef DONT_BLKDEV_GET
   1.184      blkdev_put(x->bdev);
   1.185 -#endif
   1.186 -
   1.187      kfree(x);
   1.188  
   1.189      shrink->status = BLKIF_BE_STATUS_OKAY;
   1.190 -
   1.191 - out:
   1.192 -    spin_unlock(&blkif->vbd_lock);
   1.193  }
   1.194  
   1.195  
   1.196 @@ -265,8 +256,6 @@ void vbd_destroy(blkif_be_vbd_destroy_t 
   1.197          return;
   1.198      }
   1.199  
   1.200 -    spin_lock(&blkif->vbd_lock);
   1.201 -
   1.202      rb = blkif->vbd_rb.rb_node;
   1.203      while ( rb != NULL )
   1.204      {
   1.205 @@ -280,10 +269,13 @@ void vbd_destroy(blkif_be_vbd_destroy_t 
   1.206      }
   1.207  
   1.208      destroy->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
   1.209 -    goto out;
   1.210 +    return;
   1.211  
   1.212   found:
   1.213 +    spin_lock(&blkif->vbd_lock);
   1.214      rb_erase(rb, &blkif->vbd_rb);
   1.215 +    spin_unlock(&blkif->vbd_lock);
   1.216 +
   1.217      x = vbd->extents;
   1.218      kfree(vbd);
   1.219  
   1.220 @@ -293,9 +285,6 @@ void vbd_destroy(blkif_be_vbd_destroy_t 
   1.221          kfree(x);
   1.222          x = t;
   1.223      }
   1.224 -    
   1.225 - out:
   1.226 -    spin_unlock(&blkif->vbd_lock);
   1.227  }
   1.228  
   1.229  
   1.230 @@ -404,6 +393,7 @@ int vbd_translate(phys_seg_t *pseg, blki
   1.231      blkif_sector_t     sec_off;
   1.232      unsigned long      nr_secs;
   1.233  
   1.234 +    /* Take the vbd_lock because another thread could be updating the tree. */
   1.235      spin_lock(&blkif->vbd_lock);
   1.236  
   1.237      rb = blkif->vbd_rb.rb_node;