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

[Xen-devel] [RFC v1 4/5] VBD: enlarge max segment per request in blkfront



per disk pending_req list
Signed-off-by: Ronghui Duan <ronghui.duan@xxxxxxxxx>
diff --git a/drivers/block/xen-blkback/blkback.c 
b/drivers/block/xen-blkback/blkback.c
index b4767f5..45eda98 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -64,49 +64,6 @@ MODULE_PARM_DESC(reqs, "Number of blkback requests to 
allocate");
 static unsigned int log_stats;
 module_param(log_stats, int, 0644);
 
-struct seg_buf {
-        unsigned long buf;
-        unsigned int nsec;
-};
-
-/*
- * Each outstanding request that we've passed to the lower device layers has a
- * 'pending_req' allocated to it. Each buffer_head that completes decrements
- * the pendcnt towards zero. When it hits zero, the specified domain has a
- * response queued for it, with the saved 'id' passed back.
- */
-struct pending_req {
-       struct xen_blkif        *blkif;
-       u64                     id;
-       int                     nr_pages;
-       atomic_t                pendcnt;
-       unsigned short          operation;
-       int                     status;
-       struct list_head        free_list;
-       struct gnttab_map_grant_ref     *map;
-       struct gnttab_unmap_grant_ref   *unmap;
-       struct seg_buf                  *seg;
-       struct bio                      **biolist;
-       struct page                     **pages;
-};
-
-#define BLKBACK_INVALID_HANDLE (~0)
-
-struct xen_blkbk {
-       struct pending_req      *pending_reqs;
-       /* List of all 'pending_req' available */
-       struct list_head        pending_free;
-       /* And its spinlock. */
-       spinlock_t              pending_free_lock;
-       wait_queue_head_t       pending_free_wq;
-       /* The list of all pages that are available. */
-       struct page             **pending_pages;
-       /* And the grant handles that are available. */
-       grant_handle_t          *pending_grant_handles;
-};
-
-static struct xen_blkbk *blkbk;
-
 /*
  * Little helpful macro to figure out the index and virtual address of the
  * pending_pages[..]. For each 'pending_req' we have have up to
@@ -115,20 +72,20 @@ static struct xen_blkbk *blkbk;
  */
 static inline int vaddr_pagenr(struct pending_req *req, int seg)
 {
-       return (req - blkbk->pending_reqs) *
-               BLKIF_MAX_SEGMENTS_PER_REQUEST + seg;
+       return (req - req->blkif->blkbk->pending_reqs) *
+               req->blkif->ops->max_seg + seg;
 }
 
 #define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)]
 
 static inline unsigned long vaddr(struct pending_req *req, int seg)
 {
-       unsigned long pfn = page_to_pfn(blkbk->pending_page(req, seg));
+       unsigned long pfn = page_to_pfn(req->blkif->blkbk->pending_page(req, 
seg));
        return (unsigned long)pfn_to_kaddr(pfn);
 }
 
 #define pending_handle(_req, _seg) \
-       (blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)])
+       (_req->blkif->blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)])
 
 
 static int do_block_io_op(struct xen_blkif *blkif);
@@ -143,6 +100,7 @@ static void make_response(struct xen_blkif *blkif, u64 id,
  */
 static void free_req(struct pending_req *req)
 {
+       struct xen_blkbk *blkbk = req->blkif->blkbk;
        unsigned long flags;
        int was_empty;
 
@@ -162,8 +120,9 @@ static void free_req(struct pending_req *req)
 /*
  * Retrieve from the 'pending_reqs' a free pending_req structure to be used.
  */
-static struct pending_req *alloc_req(void)
+static struct pending_req *alloc_req(struct xen_blkif *blkif)
 {
+       struct xen_blkbk *blkbk = blkif->blkbk;
        struct pending_req *req = NULL;
        unsigned long flags;
        unsigned int max_seg = BLKIF_MAX_SEGMENTS_PER_REQUEST;
@@ -173,6 +132,7 @@ static struct pending_req *alloc_req(void)
                req = list_entry(blkbk->pending_free.next, struct pending_req,
                                 free_list);
                list_del(&req->free_list);
+               req->blkif = blkif;
        }
        spin_unlock_irqrestore(&blkbk->pending_free_lock, flags);
        
@@ -319,8 +279,8 @@ int xen_blkif_schedule(void *arg)
                        blkif->wq,
                        blkif->waiting_reqs || kthread_should_stop());
                wait_event_interruptible(
-                       blkbk->pending_free_wq,
-                       !list_empty(&blkbk->pending_free) ||
+                       blkif->blkbk->pending_free_wq,
+                       !list_empty(&blkif->blkbk->pending_free) ||
                        kthread_should_stop());
 
                blkif->waiting_reqs = 0;
@@ -395,7 +355,8 @@ static int xen_blkbk_map(struct blkif_request *req,
                                  pending_req->blkif->domid);
        }
 
-       ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), 
nseg);
+       ret = gnttab_map_refs(map, NULL,
+               &pending_req->blkif->blkbk->pending_page(pending_req, 0), nseg);
        BUG_ON(ret);
 
        /*
@@ -580,7 +541,7 @@ __do_block_io_op(struct xen_blkif *blkif)
                        break;
                }
 
-               pending_req = alloc_req();
+               pending_req = alloc_req(blkif);
                if (NULL == pending_req) {
                        blkif->st_oo_req++;
                        more_to_do = 1;
@@ -742,7 +703,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
        for (i = 0; i < nseg; i++) {
                while ((bio == NULL) ||
                       (bio_add_page(bio,
-                                    blkbk->pending_page(pending_req, i),
+                                    blkif->blkbk->pending_page(pending_req, i),
                                     seg[i].nsec << 9,
                                     seg[i].buf & ~PAGE_MASK) == 0)) {
 
@@ -867,35 +828,34 @@ static void make_response(struct xen_blkif *blkif, u64 id,
                notify_remote_via_irq(blkif->irq);
 }
 
-static int __init xen_blkif_init(void)
+int xen_blkif_init_blkbk(struct xen_blkif *blkif)
 {
-       int i, mmap_pages;
        int rc = 0;
+       int i, mmap_pages;
+       struct xen_blkbk *blkbk;
 
-       if (!xen_domain())
-               return -ENODEV;
-
-       blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
-       if (!blkbk) {
+       blkif->blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
+       if (!blkif->blkbk) {
                pr_alert(DRV_PFX "%s: out of memory!\n", __func__);
                return -ENOMEM;
        }
 
-       mmap_pages = xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
-
-       blkbk->pending_reqs          = kzalloc(sizeof(blkbk->pending_reqs[0]) *
-                                       xen_blkif_reqs, GFP_KERNEL);
-       blkbk->pending_grant_handles = 
kmalloc(sizeof(blkbk->pending_grant_handles[0]) *
-                                       mmap_pages, GFP_KERNEL);
-       blkbk->pending_pages         = kzalloc(sizeof(blkbk->pending_pages[0]) *
-                                       mmap_pages, GFP_KERNEL);
-
-       if (!blkbk->pending_reqs || !blkbk->pending_grant_handles ||
-           !blkbk->pending_pages) {
-               rc = -ENOMEM;
+       blkbk = blkif->blkbk;
+       mmap_pages = xen_blkif_reqs * blkif->ops->max_seg;
+
+       blkbk->pending_reqs = kzalloc(sizeof(blkbk->pending_reqs[0]) *
+                                     xen_blkif_reqs, GFP_KERNEL);
+       blkbk->pending_grant_handles = 
kzalloc(sizeof(blkbk->pending_grant_handles[0])
+                                              * mmap_pages, GFP_KERNEL);
+       blkbk->pending_pages = kzalloc(sizeof(blkbk->pending_pages[0]) *
+                                      mmap_pages, GFP_KERNEL);
+ 
+       if (!blkbk->pending_reqs || !blkbk->pending_grant_handles ||
+           !blkbk->pending_pages) {
+               rc = -ENOMEM;
                goto out_of_memory;
        }
-
+       
        for (i = 0; i < mmap_pages; i++) {
                blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
                blkbk->pending_pages[i] = alloc_page(GFP_KERNEL);
@@ -904,10 +864,6 @@ static int __init xen_blkif_init(void)
                        goto out_of_memory;
                }
        }
-       rc = xen_blkif_interface_init();
-       if (rc)
-               goto failed_init;
-
        INIT_LIST_HEAD(&blkbk->pending_free);
        spin_lock_init(&blkbk->pending_free_lock);
        init_waitqueue_head(&blkbk->pending_free_wq);
@@ -916,15 +872,10 @@ static int __init xen_blkif_init(void)
                list_add_tail(&blkbk->pending_reqs[i].free_list,
                              &blkbk->pending_free);
 
-       rc = xen_blkif_xenbus_init();
-       if (rc)
-               goto failed_init;
-
        return 0;
 
- out_of_memory:
+out_of_memory:
        pr_alert(DRV_PFX "%s: out of memory\n", __func__);
- failed_init:
        kfree(blkbk->pending_reqs);
        kfree(blkbk->pending_grant_handles);
        if (blkbk->pending_pages) {
@@ -935,7 +886,7 @@ static int __init xen_blkif_init(void)
                kfree(blkbk->pending_pages);
        }
        kfree(blkbk);
-       blkbk = NULL;
+       blkif->blkbk = NULL;
        return rc;
 }
 
@@ -947,6 +898,24 @@ struct blkback_ring_operation blkback_ring_ops = {
        .max_seg = BLKIF_MAX_SEGMENTS_PER_REQUEST,
 };
 
+static int __init xen_blkif_init(void)
+{
+       int rc = 0;
+
+       if (!xen_domain())
+               return -ENODEV;
+
+       rc = xen_blkif_interface_init();
+       if (rc)
+               return rc;
+
+       rc = xen_blkif_xenbus_init();
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
 module_init(xen_blkif_init);
 
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/block/xen-blkback/common.h 
b/drivers/block/xen-blkback/common.h
index ce5556a..80e8acc 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -169,6 +169,7 @@ struct xen_vbd {
 
 struct backend_info;
 struct xen_blkif;
+struct xen_blkbk;
 
 struct blkback_ring_operation {
        void *(*get_back_ring) (struct xen_blkif *blkif);
@@ -190,6 +191,7 @@ struct xen_blkif {
        enum blkif_backring_type blk_backring_type;
        union blkif_back_rings  blk_rings;
        void                    *blk_ring;
+       struct xen_blkbk        *blkbk;
        /* The VBD attached to this interface. */
        struct xen_vbd          vbd;
        /* Back pointer to the backend_info. */
@@ -221,6 +223,46 @@ struct xen_blkif {
        wait_queue_head_t       waiting_to_free;
 };
 
+struct seg_buf {
+        unsigned long buf;
+        unsigned int nsec;
+};
+
+/*
+ * Each outstanding request that we've passed to the lower device layers has a
+ * 'pending_req' allocated to it. Each buffer_head that completes decrements
+ * the pendcnt towards zero. When it hits zero, the specified domain has a
+ * response queued for it, with the saved 'id' passed back.
+ */
+struct pending_req {
+       struct xen_blkif        *blkif;
+       u64                     id;
+       int                     nr_pages;
+       atomic_t                pendcnt;
+       unsigned short          operation;
+       int                     status;
+       struct list_head        free_list;
+       struct gnttab_map_grant_ref     *map;
+       struct gnttab_unmap_grant_ref   *unmap;
+       struct seg_buf                  *seg;
+       struct bio                      **biolist;
+       struct page                     **pages;
+};
+
+#define BLKBACK_INVALID_HANDLE (~0)
+
+struct xen_blkbk {
+       struct pending_req      *pending_reqs;
+       /* List of all 'pending_req' available */
+       struct list_head        pending_free;
+       /* And its spinlock. */
+       spinlock_t              pending_free_lock;
+       wait_queue_head_t       pending_free_wq;
+       /* The list of all pages that are available. */
+       struct page             **pending_pages;
+       /* And the grant handles that are available. */
+       grant_handle_t          *pending_grant_handles;
+};
 
 #define vbd_sz(_v)     ((_v)->bdev->bd_part ? \
                         (_v)->bdev->bd_part->nr_sects : \
@@ -243,6 +285,8 @@ int xen_blkif_interface_init(void);
 
 int xen_blkif_xenbus_init(void);
 
+int xen_blkif_init_blkbk(struct xen_blkif *blkif);
+
 irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
 int xen_blkif_schedule(void *arg);
 
diff --git a/drivers/block/xen-blkback/xenbus.c 
b/drivers/block/xen-blkback/xenbus.c
index 850ecad..8b0d496 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -769,6 +769,12 @@ static int connect_ring(struct backend_info *be)
                return err;
        }
 
+       err = xen_blkif_init_blkbk(be->blkif);
+       if (err) {
+               xenbus_dev_fatal(dev, err, "xen blkif init blkbk fails\n");
+               return err;
+       }
+       
        return 0;
 }
 


-ronghui


Attachment: vbd_enlarge_segments_04.patch
Description: vbd_enlarge_segments_04.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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