[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] More cleanups and fix free_blkif from wrong context bug (thanks Keir!).



# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 49b67f0f67355c4e3f1f30912811c600309aa78d
# Parent  a826ad59b3eaf35a4ceed7fda47f1a550e1d62e7
More cleanups and fix free_blkif from wrong context bug (thanks Keir!).
Signed-off-by: Christian Limpach <Christian.Limpach@xxxxxxxxxxxx>

diff -r a826ad59b3ea -r 49b67f0f6735 
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Aug 23 15:43:04 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/common.h Tue Aug 23 16:37:59 2005
@@ -5,7 +5,6 @@
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
-#include <linux/rbtree.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
@@ -30,12 +29,19 @@
 #define DPRINTK(_f, _a...) ((void)0)
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-typedef struct rb_root rb_root_t;
-typedef struct rb_node rb_node_t;
-#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
 struct block_device;
 #endif
+
+struct vbd {
+    blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
+    unsigned char  readonly;    /* Non-zero -> read-only */
+    unsigned char  type;        /* VDISK_xxx */
+    blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
+    struct block_device *bdev;
+
+    int active;
+}; 
 
 typedef struct blkif_st {
     /* Unique identifier for this interface. */
@@ -48,7 +54,7 @@
     /* Comms information. */
     blkif_back_ring_t blk_ring;
     /* VBDs attached to this interface. */
-    struct vbd *vbd;
+    struct vbd        vbd;
     /* Private fields. */
     enum { DISCONNECTED, CONNECTED } status;
     /*
@@ -64,7 +70,7 @@
     spinlock_t       blk_ring_lock;
     atomic_t         refcnt;
 
-    struct work_struct work;
+    struct work_struct free_work;
     u16 shmem_handle;
     unsigned long shmem_vaddr;
     grant_ref_t shmem_ref;
@@ -76,23 +82,22 @@
 int  blkif_disconnect(blkif_be_disconnect_t *disconnect, u8 rsp_id);
 void blkif_disconnect_complete(blkif_t *blkif);
 blkif_t *alloc_blkif(domid_t domid);
-void free_blkif(blkif_t *blkif);
+void free_blkif_callback(blkif_t *blkif);
 int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn);
 
 #define blkif_get(_b) (atomic_inc(&(_b)->refcnt))
 #define blkif_put(_b)                             \
     do {                                          \
         if ( atomic_dec_and_test(&(_b)->refcnt) ) \
-            free_blkif(_b);                      \
+            free_blkif_callback(_b);             \
     } while (0)
 
-struct vbd;
-void vbd_free(blkif_t *blkif, struct vbd *vbd);
-
 /* Creates inactive vbd. */
-struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t 
pdevice, int readonly);
+int vbd_create(blkif_t *blkif, blkif_vdev_t vdevice, blkif_pdev_t pdevice,
+              int readonly);
 int vbd_is_active(struct vbd *vbd);
-void vbd_activate(blkif_t *blkif, struct vbd *vbd);
+void vbd_activate(struct vbd *vbd);
+void vbd_free(struct vbd *vbd);
 
 unsigned long vbd_size(struct vbd *vbd);
 unsigned int vbd_info(struct vbd *vbd);
diff -r a826ad59b3ea -r 49b67f0f6735 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Tue Aug 23 
15:43:04 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Tue Aug 23 
16:37:59 2005
@@ -108,9 +108,10 @@
     return 0;
 }
 
-void free_blkif(blkif_t *blkif)
+static void free_blkif(void *arg)
 {
     evtchn_op_t op = { .cmd = EVTCHNOP_close };
+    blkif_t *blkif = (blkif_t *)arg;
 
     op.u.close.port = blkif->evtchn;
     op.u.close.dom = DOMID_SELF;
@@ -118,6 +119,9 @@
     op.u.close.port = blkif->remote_evtchn;
     op.u.close.dom = blkif->domid;
     HYPERVISOR_event_channel_op(&op);
+
+    if (vbd_is_active(&blkif->vbd))
+       vbd_free(&blkif->vbd);
 
     if (blkif->evtchn)
         unbind_evtchn_from_irqhandler(blkif->evtchn, blkif);
@@ -130,6 +134,12 @@
     kmem_cache_free(blkif_cachep, blkif);
 }
 
+void free_blkif_callback(blkif_t *blkif)
+{
+    INIT_WORK(&blkif->free_work, free_blkif, (void *)blkif);
+    schedule_work(&blkif->free_work);
+}
+
 void __init blkif_interface_init(void)
 {
     blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t), 
diff -r a826ad59b3ea -r 49b67f0f6735 
linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Tue Aug 23 15:43:04 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/vbd.c    Tue Aug 23 16:37:59 2005
@@ -8,16 +8,6 @@
 
 #include "common.h"
 #include <asm-xen/xenbus.h>
-
-struct vbd {
-    blkif_vdev_t   handle;      /* what the domain refers to this vbd as */
-    unsigned char  readonly;    /* Non-zero -> read-only */
-    unsigned char  type;        /* VDISK_xxx */
-    blkif_pdev_t   pdevice;     /* phys device that this vbd maps to */
-    struct block_device *bdev;
-
-    int active;
-}; 
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static inline dev_t vbd_map_devnum(blkif_pdev_t cookie)
@@ -53,18 +43,12 @@
        return vbd->active;
 }
 
-struct vbd *vbd_create(blkif_t *blkif, blkif_vdev_t handle,
-                      blkif_pdev_t pdevice, int readonly)
+int vbd_create(blkif_t *blkif, blkif_vdev_t handle,
+              blkif_pdev_t pdevice, int readonly)
 {
-    struct vbd *vbd, *err; 
+    struct vbd *vbd;
 
-    if ( unlikely((vbd = kmalloc(sizeof(struct vbd), GFP_KERNEL)) == NULL) )
-    {
-        DPRINTK("vbd_create: out of memory\n");
-       return ERR_PTR(-ENOMEM);
-    }
-
-    blkif->vbd = vbd;
+    vbd = &blkif->vbd;
     vbd->handle   = handle; 
     vbd->readonly = readonly;
     vbd->type     = 0;
@@ -79,16 +63,14 @@
     if ( IS_ERR(vbd->bdev) )
     {
         DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
-        err = ERR_PTR(-ENOENT);
-       goto out;
+        return -ENOENT;
     }
 
     if ( (vbd->bdev->bd_disk == NULL) )
     {
         DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
         bdev_put(vbd->bdev);
-        err = ERR_PTR(-ENOENT);
-       goto out;
+        return -ENOENT;
     }
 
     if ( vbd->bdev->bd_disk->flags & GENHD_FL_CD )
@@ -99,41 +81,33 @@
     if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
     {
         DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
-        err = ERR_PTR(-ENOENT);
-       goto out;
+        return -ENOENT;
     }
 #endif
 
     DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
             handle, blkif->domid);
-    return vbd;
-
- out:
-    kfree(vbd);
-    return err;
+    return 0;
 }
 
-void vbd_activate(blkif_t *blkif, struct vbd *vbd)
+void vbd_activate(struct vbd *vbd)
 {
     BUG_ON(vbd_is_active(vbd));
 
     /* Now we're active. */
     vbd->active = 1;
-    blkif_get(blkif);
 }
 
-void vbd_free(blkif_t *blkif, struct vbd *vbd)
+void vbd_free(struct vbd *vbd)
 {
-    if (vbd_is_active(vbd)) {
-       blkif_put(blkif);
-    }
+    if (vbd_is_active(vbd))
+       vbd->active = 0;
     bdev_put(vbd->bdev);
-    kfree(vbd);
 }
 
 int vbd_translate(struct phys_req *req, blkif_t *blkif, int operation)
 {
-    struct vbd *vbd = blkif->vbd;
+    struct vbd *vbd = &blkif->vbd;
     int rc = -EACCES;
 
     if ((operation == WRITE) && vbd->readonly)
diff -r a826ad59b3ea -r 49b67f0f6735 
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Aug 23 15:43:04 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c Tue Aug 23 16:37:59 2005
@@ -26,7 +26,6 @@
 
        /* our communications channel */
        blkif_t *blkif;
-       struct vbd *vbd;
 
        long int frontend_id;
        long int pdev;
@@ -47,8 +46,6 @@
        if (be->watch.node)
                unregister_xenbus_watch(&be->watch);
        unregister_xenbus_watch(&be->backend_watch);
-       if (be->vbd)
-               vbd_free(be->blkif, be->vbd);
        if (be->blkif)
                blkif_put(be->blkif);
        if (be->frontpath)
@@ -72,7 +69,7 @@
                device_unregister(&be->dev->dev);
                return;
        }
-       if (vbd_is_active(be->vbd))
+       if (vbd_is_active(&be->blkif->vbd))
                return;
 
        err = xenbus_gather(be->frontpath, "grant-id", "%lu", &sharedmfn,
@@ -105,7 +102,7 @@
        }
 
        err = xenbus_printf(be->dev->nodename, "sectors", "%lu",
-                           vbd_size(be->vbd));
+                           vbd_size(&be->blkif->vbd));
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/sectors",
                                 be->dev->nodename);
@@ -114,14 +111,14 @@
 
        /* FIXME: use a typename instead */
        err = xenbus_printf(be->dev->nodename, "info", "%u",
-                           vbd_info(be->vbd));
+                           vbd_info(&be->blkif->vbd));
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/info",
                                 be->dev->nodename);
                goto abort;
        }
        err = xenbus_printf(be->dev->nodename, "sector-size", "%lu",
-                           vbd_secsize(be->vbd));
+                           vbd_secsize(&be->blkif->vbd));
        if (err) {
                xenbus_dev_error(be->dev, err, "writing %s/sector-size",
                                 be->dev->nodename);
@@ -140,7 +137,7 @@
        }
 
        /* We're ready, activate. */
-       vbd_activate(be->blkif, be->vbd);
+       vbd_activate(&be->blkif->vbd);
 
        xenbus_transaction_end(0);
        xenbus_dev_ok(be->dev);
@@ -235,13 +232,9 @@
                        goto device_fail;
                }
 
-               be->vbd = vbd_create(be->blkif, handle, be->pdev,
-                                    be->readonly);
-               if (IS_ERR(be->vbd)) {
-                       err = PTR_ERR(be->vbd);
-                       be->vbd = NULL;
+               err = vbd_create(be->blkif, handle, be->pdev, be->readonly);
+               if (err)
                        goto device_fail;
-               }
 
                frontend_changed(&be->watch, be->frontpath);
        }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.