WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] More cleanups and fix free_blkif from wrong context bug

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] More cleanups and fix free_blkif from wrong context bug (thanks Keir!).
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 23 Aug 2005 18:36:23 +0000
Delivery-date: Wed, 24 Aug 2005 09:07:32 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] More cleanups and fix free_blkif from wrong context bug (thanks Keir!)., Xen patchbot -unstable <=