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

[Xen-devel] [RFC PATCH 44/60] hyper_dmabuf: proper handling of sgt_info->priv



sgt_info->priv will be used to store user private info passed in
ioctl. Data in sgt_info->priv is transfered via comm channel to
the importer VM whenever DMA_BUF is exported to keep the private
data synchroized across VMs.

This patch also adds hyper_dmabuf_send_export_msg that replaces
some of export_remote_ioctl to make it more readable and
compact.

Signed-off-by: Dongwon Kim <dongwon.kim@xxxxxxxxx>
---
 drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c  | 110 ++++++++++++++-----------
 drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h |   6 +-
 2 files changed, 65 insertions(+), 51 deletions(-)

diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c 
b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c
index 3215003..dfdb889 100644
--- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c
+++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c
@@ -82,17 +82,64 @@ static int hyper_dmabuf_rx_ch_setup_ioctl(struct file 
*filp, void *data)
        return ret;
 }
 
+static int hyper_dmabuf_send_export_msg(struct hyper_dmabuf_sgt_info *sgt_info,
+                                       struct hyper_dmabuf_pages_info 
*page_info)
+{
+       struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops;
+       struct hyper_dmabuf_req *req;
+       int operands[12] = {0};
+       int ret, i;
+
+       /* now create request for importer via ring */
+       operands[0] = sgt_info->hid.id;
+
+       for (i=0; i<3; i++)
+               operands[i+1] = sgt_info->hid.rng_key[i];
+
+       if (page_info) {
+               operands[4] = page_info->nents;
+               operands[5] = page_info->frst_ofst;
+               operands[6] = page_info->last_len;
+               operands[7] = ops->share_pages (page_info->pages, 
sgt_info->hyper_dmabuf_rdomain,
+                                               page_info->nents, 
&sgt_info->refs_info);
+               if (operands[7] < 0) {
+                       dev_err(hyper_dmabuf_private.device, "pages sharing 
failed\n");
+                       return -1;
+               }
+       }
+
+       /* driver/application specific private info, max 4x4 bytes */
+       memcpy(&operands[8], &sgt_info->priv[0], sizeof(unsigned int) * 4);
+
+       req = kcalloc(1, sizeof(*req), GFP_KERNEL);
+
+       if(!req) {
+               dev_err(hyper_dmabuf_private.device, "no more space left\n");
+               return -1;
+       }
+
+       /* composing a message to the importer */
+       hyper_dmabuf_create_request(req, HYPER_DMABUF_EXPORT, &operands[0]);
+
+       ret = ops->send_req(sgt_info->hyper_dmabuf_rdomain, req, false);
+
+       if(ret) {
+               dev_err(hyper_dmabuf_private.device, "error while 
communicating\n");
+       }
+
+       kfree(req);
+
+       return ret;
+}
+
 static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 {
        struct ioctl_hyper_dmabuf_export_remote *export_remote_attr;
-       struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops;
        struct dma_buf *dma_buf;
        struct dma_buf_attachment *attachment;
        struct sg_table *sgt;
        struct hyper_dmabuf_pages_info *page_info;
        struct hyper_dmabuf_sgt_info *sgt_info;
-       struct hyper_dmabuf_req *req;
-       int operands[MAX_NUMBER_OF_OPERANDS];
        hyper_dmabuf_id_t hid;
        int i;
        int ret = 0;
@@ -138,6 +185,13 @@ static int hyper_dmabuf_export_remote_ioctl(struct file 
*filp, void *data)
                                        }
                                        sgt_info->unexport_scheduled = 0;
                                }
+
+                               /* update private data in sgt_info with new 
ones */
+                               memcpy(&sgt_info->priv[0], 
&export_remote_attr->priv[0], sizeof(unsigned int) * 4);
+
+                               /* TODO: need to send this private info to the 
importer so that those
+                                * on importer's side are also updated */
+
                                dma_buf_put(dma_buf);
                                export_remote_attr->hid = hid;
                                return 0;
@@ -225,6 +279,9 @@ static int hyper_dmabuf_export_remote_ioctl(struct file 
*filp, void *data)
        INIT_LIST_HEAD(&sgt_info->va_kmapped->list);
        INIT_LIST_HEAD(&sgt_info->va_vmapped->list);
 
+       /* copy private data to sgt_info */
+       memcpy(&sgt_info->priv[0], &export_remote_attr->priv[0], 
sizeof(unsigned int) * 4);
+
        page_info = hyper_dmabuf_ext_pgs(sgt);
        if (!page_info) {
                dev_err(hyper_dmabuf_private.device, "failed to construct 
page_info\n");
@@ -236,53 +293,15 @@ static int hyper_dmabuf_export_remote_ioctl(struct file 
*filp, void *data)
        /* now register it to export list */
        hyper_dmabuf_register_exported(sgt_info);
 
-       page_info->hyper_dmabuf_rdomain = sgt_info->hyper_dmabuf_rdomain;
-       page_info->hid = sgt_info->hid; /* may not be needed */
-
        export_remote_attr->hid = sgt_info->hid;
 
-       /* now create request for importer via ring */
-       operands[0] = page_info->hid.id;
-
-       for (i=0; i<3; i++)
-               operands[i+1] = page_info->hid.rng_key[i];
-
-       operands[4] = page_info->nents;
-       operands[5] = page_info->frst_ofst;
-       operands[6] = page_info->last_len;
-       operands[7] = ops->share_pages (page_info->pages, 
export_remote_attr->remote_domain,
-                                       page_info->nents, &sgt_info->refs_info);
-       if (operands[7] < 0) {
-               dev_err(hyper_dmabuf_private.device, "pages sharing failed\n");
-               goto fail_map_req;
-       }
-
-       /* driver/application specific private info, max 4x4 bytes */
-       operands[8] = export_remote_attr->priv[0];
-       operands[9] = export_remote_attr->priv[1];
-       operands[10] = export_remote_attr->priv[2];
-       operands[11] = export_remote_attr->priv[3];
-
-       req = kcalloc(1, sizeof(*req), GFP_KERNEL);
+       ret = hyper_dmabuf_send_export_msg(sgt_info, page_info);
 
-       if(!req) {
-               dev_err(hyper_dmabuf_private.device, "no more space left\n");
-               goto fail_map_req;
-       }
-
-       /* composing a message to the importer */
-       hyper_dmabuf_create_request(req, HYPER_DMABUF_EXPORT, &operands[0]);
-
-       ret = ops->send_req(export_remote_attr->remote_domain, req, false);
-
-       if(ret) {
-               dev_err(hyper_dmabuf_private.device, "error while 
communicating\n");
+       if (ret < 0) {
+               dev_err(hyper_dmabuf_private.device, "failed to send out the 
export request\n");
                goto fail_send_request;
        }
 
-       /* free msg */
-       kfree(req);
-
        /* free page_info */
        kfree(page_info->pages);
        kfree(page_info);
@@ -294,9 +313,6 @@ static int hyper_dmabuf_export_remote_ioctl(struct file 
*filp, void *data)
 /* Clean-up if error occurs */
 
 fail_send_request:
-       kfree(req);
-
-fail_map_req:
        hyper_dmabuf_remove_exported(sgt_info->hid);
 
        /* free page_info */
diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h 
b/drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h
index 991a8d4..a1d3ec6 100644
--- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h
+++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h
@@ -51,8 +51,6 @@ struct vmap_vaddr_list {
 
 /* Exporter builds pages_info before sharing pages */
 struct hyper_dmabuf_pages_info {
-        hyper_dmabuf_id_t hid; /* unique id to reference dmabuf in source 
domain */
-        int hyper_dmabuf_rdomain; /* currenting considering just one remote 
domain access it */
         int frst_ofst; /* offset of data in the first page */
         int last_len; /* length of data in the last page */
         int nents; /* # of pages */
@@ -71,7 +69,7 @@ struct hyper_dmabuf_sgt_info {
        int hyper_dmabuf_rdomain; /* domain importing this sgt */
 
        struct dma_buf *dma_buf; /* needed to store this for freeing it later */
-       int nents; /* number of pages, which may be different than sgt->nents */
+       int nents;
 
        /* list of remote activities on dma_buf */
        struct sgt_list *active_sgts;
@@ -92,7 +90,7 @@ struct hyper_dmabuf_sgt_info {
         * uses releases hyper_dmabuf device
         */
        struct file *filp;
-       int private[4]; /* device specific info (e.g. image's meta info?) */
+       int priv[4]; /* device specific info (e.g. image's meta info?) */
 };
 
 /* Importer store references (before mapping) on shared pages
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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