All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dongwon Kim <dongwon.kim@intel.com>
To: linux-kernel@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
	xen-devel@lists.xenproject.org
Cc: sumit.semwal@linaro.org, dongwon.kim@intel.com,
	dri-devel@lists.freedesktop.org, mateuszx.potrola@intel.com
Subject: [RFC PATCH v2 4/9] hyper_dmabuf: user private data attached to hyper_DMABUF
Date: Tue, 13 Feb 2018 17:50:03 -0800	[thread overview]
Message-ID: <20180214015008.9513-5-dongwon.kim__15246.8656575822$1518573039$gmane$org@intel.com> (raw)
In-Reply-To: <20180214015008.9513-1-dongwon.kim@intel.com>

Define a private data (e.g. meta data for the buffer) attached to
each hyper_DMABUF structure. This data is provided by userapace via
export_remote IOCTL and its size can be up to 192 bytes.

Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Signed-off-by: Mateusz Polrola <mateuszx.potrola@intel.com>
---
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c  | 83 ++++++++++++++++++++--
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c    | 36 +++++++++-
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h    |  2 +-
 .../dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c   |  1 +
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h | 12 ++++
 include/uapi/linux/hyper_dmabuf.h                  |  4 ++
 6 files changed, 132 insertions(+), 6 deletions(-)

diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
index 020a5590a254..168ccf98f710 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
@@ -103,6 +103,11 @@ static int send_export_msg(struct exported_sgt_info *exported,
 		}
 	}
 
+	op[8] = exported->sz_priv;
+
+	/* driver/application specific private info */
+	memcpy(&op[9], exported->priv, op[8]);
+
 	req = kcalloc(1, sizeof(*req), GFP_KERNEL);
 
 	if (!req)
@@ -120,8 +125,9 @@ static int send_export_msg(struct exported_sgt_info *exported,
 
 /* Fast path exporting routine in case same buffer is already exported.
  *
- * If same buffer is still valid and exist in EXPORT LIST it returns 0 so
- * that remaining normal export process can be skipped.
+ * If same buffer is still valid and exist in EXPORT LIST, it only updates
+ * user-private data for the buffer and returns 0 so that that it can skip
+ * normal export process.
  *
  * If "unexport" is scheduled for the buffer, it cancels it since the buffer
  * is being re-exported.
@@ -129,7 +135,7 @@ static int send_export_msg(struct exported_sgt_info *exported,
  * return '1' if reexport is needed, return '0' if succeeds, return
  * Kernel error code if something goes wrong
  */
-static int fastpath_export(hyper_dmabuf_id_t hid)
+static int fastpath_export(hyper_dmabuf_id_t hid, int sz_priv, char *priv)
 {
 	int reexport = 1;
 	int ret = 0;
@@ -155,6 +161,46 @@ static int fastpath_export(hyper_dmabuf_id_t hid)
 		exported->unexport_sched = false;
 	}
 
+	/* if there's any change in size of private data.
+	 * we reallocate space for private data with new size
+	 */
+	if (sz_priv != exported->sz_priv) {
+		kfree(exported->priv);
+
+		/* truncating size */
+		if (sz_priv > MAX_SIZE_PRIV_DATA)
+			exported->sz_priv = MAX_SIZE_PRIV_DATA;
+		else
+			exported->sz_priv = sz_priv;
+
+		exported->priv = kcalloc(1, exported->sz_priv,
+					 GFP_KERNEL);
+
+		if (!exported->priv) {
+			hyper_dmabuf_remove_exported(exported->hid);
+			hyper_dmabuf_cleanup_sgt_info(exported, true);
+			kfree(exported);
+			return -ENOMEM;
+		}
+	}
+
+	/* update private data in sgt_info with new ones */
+	ret = copy_from_user(exported->priv, priv, exported->sz_priv);
+	if (ret) {
+		dev_err(hy_drv_priv->dev,
+			"Failed to load a new private data\n");
+		ret = -EINVAL;
+	} else {
+		/* send an export msg for updating priv in importer */
+		ret = send_export_msg(exported, NULL);
+
+		if (ret < 0) {
+			dev_err(hy_drv_priv->dev,
+				"Failed to send a new private data\n");
+			ret = -EBUSY;
+		}
+	}
+
 	return ret;
 }
 
@@ -191,7 +237,8 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 					     export_remote_attr->remote_domain);
 
 	if (hid.id != -1) {
-		ret = fastpath_export(hid);
+		ret = fastpath_export(hid, export_remote_attr->sz_priv,
+				      export_remote_attr->priv);
 
 		/* return if fastpath_export succeeds or
 		 * gets some fatal error
@@ -225,6 +272,24 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 		goto fail_sgt_info_creation;
 	}
 
+	/* possible truncation */
+	if (export_remote_attr->sz_priv > MAX_SIZE_PRIV_DATA)
+		exported->sz_priv = MAX_SIZE_PRIV_DATA;
+	else
+		exported->sz_priv = export_remote_attr->sz_priv;
+
+	/* creating buffer for private data of buffer */
+	if (exported->sz_priv != 0) {
+		exported->priv = kcalloc(1, exported->sz_priv, GFP_KERNEL);
+
+		if (!exported->priv) {
+			ret = -ENOMEM;
+			goto fail_priv_creation;
+		}
+	} else {
+		dev_err(hy_drv_priv->dev, "size is 0\n");
+	}
+
 	exported->hid = hyper_dmabuf_get_hid();
 
 	/* no more exported dmabuf allowed */
@@ -279,6 +344,10 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 	INIT_LIST_HEAD(&exported->va_kmapped->list);
 	INIT_LIST_HEAD(&exported->va_vmapped->list);
 
+	/* copy private data to sgt_info */
+	ret = copy_from_user(exported->priv, export_remote_attr->priv,
+			     exported->sz_priv);
+
 	if (ret) {
 		dev_err(hy_drv_priv->dev,
 			"failed to load private data\n");
@@ -337,6 +406,9 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 
 fail_map_active_attached:
 	kfree(exported->active_sgts);
+	kfree(exported->priv);
+
+fail_priv_creation:
 	kfree(exported);
 
 fail_map_active_sgts:
@@ -567,6 +639,9 @@ static void delayed_unexport(struct work_struct *work)
 		/* register hyper_dmabuf_id to the list for reuse */
 		hyper_dmabuf_store_hid(exported->hid);
 
+		if (exported->sz_priv > 0 && !exported->priv)
+			kfree(exported->priv);
+
 		kfree(exported);
 	}
 }
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
index 129b2ff2af2b..7176fa8fb139 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
@@ -60,9 +60,12 @@ void hyper_dmabuf_create_req(struct hyper_dmabuf_req *req,
 		 * op5 : offset of data in the first page
 		 * op6 : length of data in the last page
 		 * op7 : top-level reference number for shared pages
+		 * op8 : size of private data (from op9)
+		 * op9 ~ : Driver-specific private data
+		 *	   (e.g. graphic buffer's meta info)
 		 */
 
-		memcpy(&req->op[0], &op[0], 8 * sizeof(int) + op[8]);
+		memcpy(&req->op[0], &op[0], 9 * sizeof(int) + op[8]);
 		break;
 
 	case HYPER_DMABUF_NOTIFY_UNEXPORT:
@@ -116,6 +119,9 @@ static void cmd_process_work(struct work_struct *work)
 		 * op5 : offset of data in the first page
 		 * op6 : length of data in the last page
 		 * op7 : top-level reference number for shared pages
+		 * op8 : size of private data (from op9)
+		 * op9 ~ : Driver-specific private data
+		 *         (e.g. graphic buffer's meta info)
 		 */
 
 		/* if nents == 0, it means it is a message only for
@@ -135,6 +141,24 @@ static void cmd_process_work(struct work_struct *work)
 				break;
 			}
 
+			/* if size of new private data is different,
+			 * we reallocate it.
+			 */
+			if (imported->sz_priv != req->op[8]) {
+				kfree(imported->priv);
+				imported->sz_priv = req->op[8];
+				imported->priv = kcalloc(1, req->op[8],
+							 GFP_KERNEL);
+				if (!imported->priv) {
+					/* set it invalid */
+					imported->valid = 0;
+					break;
+				}
+			}
+
+			/* updating priv data */
+			memcpy(imported->priv, &req->op[9], req->op[8]);
+
 			break;
 		}
 
@@ -143,6 +167,14 @@ static void cmd_process_work(struct work_struct *work)
 		if (!imported)
 			break;
 
+		imported->sz_priv = req->op[8];
+		imported->priv = kcalloc(1, req->op[8], GFP_KERNEL);
+
+		if (!imported->priv) {
+			kfree(imported);
+			break;
+		}
+
 		imported->hid.id = req->op[0];
 
 		for (i = 0; i < 3; i++)
@@ -162,6 +194,8 @@ static void cmd_process_work(struct work_struct *work)
 		dev_dbg(hy_drv_priv->dev, "\tlast len %d\n", req->op[6]);
 		dev_dbg(hy_drv_priv->dev, "\tgrefid %d\n", req->op[7]);
 
+		memcpy(imported->priv, &req->op[9], req->op[8]);
+
 		imported->valid = true;
 		hyper_dmabuf_register_imported(imported);
 
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
index 59f1528e9b1e..63a39d068d69 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
@@ -27,7 +27,7 @@
 #ifndef __HYPER_DMABUF_MSG_H__
 #define __HYPER_DMABUF_MSG_H__
 
-#define MAX_NUMBER_OF_OPERANDS 8
+#define MAX_NUMBER_OF_OPERANDS 64
 
 struct hyper_dmabuf_req {
 	unsigned int req_id;
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
index d92ae13d8a30..9032f89e0cd0 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
@@ -251,6 +251,7 @@ int hyper_dmabuf_cleanup_sgt_info(struct exported_sgt_info *exported,
 	kfree(exported->active_attached);
 	kfree(exported->va_kmapped);
 	kfree(exported->va_vmapped);
+	kfree(exported->priv);
 
 	return 0;
 }
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
index 144e3821fbc2..a1220bbf8d0c 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
@@ -101,6 +101,12 @@ struct exported_sgt_info {
 	 * the buffer can be completely freed.
 	 */
 	struct file *filp;
+
+	/* size of private */
+	size_t sz_priv;
+
+	/* private data associated with the exported buffer */
+	char *priv;
 };
 
 /* imported_sgt_info contains information about imported DMA_BUF
@@ -126,6 +132,12 @@ struct imported_sgt_info {
 	void *refs_info;
 	bool valid;
 	int importers;
+
+	/* size of private */
+	size_t sz_priv;
+
+	/* private data associated with the exported buffer */
+	char *priv;
 };
 
 #endif /* __HYPER_DMABUF_STRUCT_H__ */
diff --git a/include/uapi/linux/hyper_dmabuf.h b/include/uapi/linux/hyper_dmabuf.h
index caaae2da9d4d..36794a4af811 100644
--- a/include/uapi/linux/hyper_dmabuf.h
+++ b/include/uapi/linux/hyper_dmabuf.h
@@ -25,6 +25,8 @@
 #ifndef __LINUX_PUBLIC_HYPER_DMABUF_H__
 #define __LINUX_PUBLIC_HYPER_DMABUF_H__
 
+#define MAX_SIZE_PRIV_DATA 192
+
 typedef struct {
 	int id;
 	int rng_key[3]; /* 12bytes long random number */
@@ -56,6 +58,8 @@ struct ioctl_hyper_dmabuf_export_remote {
 	int remote_domain;
 	/* exported dma buf id */
 	hyper_dmabuf_id_t hid;
+	int sz_priv;
+	char *priv;
 };
 
 #define IOCTL_HYPER_DMABUF_EXPORT_FD \
-- 
2.16.1


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

  parent reply	other threads:[~2018-02-14  1:51 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-14  1:49 [RFC PATCH v2 0/9] hyper_dmabuf: Hyper_DMABUF driver Dongwon Kim
2018-02-14  1:49 ` Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 1/9] hyper_dmabuf: initial upload of hyper_dmabuf drv core framework Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-04-10  8:53   ` [RFC, v2, " Oleksandr Andrushchenko
2018-04-10 10:47     ` [Xen-devel] " Julien Grall
2018-04-10 11:04       ` Oleksandr Andrushchenko
2018-04-10 11:04         ` Oleksandr Andrushchenko
2018-04-10 11:04       ` Oleksandr Andrushchenko
2018-04-10 10:47     ` Julien Grall
2018-04-10  8:53   ` Oleksandr Andrushchenko
2018-02-14  1:50 ` [RFC PATCH v2 " Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 2/9] hyper_dmabuf: architecture specification and reference guide Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-02-23 16:15   ` [Xen-devel] " Roger Pau Monné
2018-02-23 16:15     ` Roger Pau Monné
2018-02-23 19:02     ` Dongwon Kim
2018-02-23 19:02     ` [Xen-devel] " Dongwon Kim
2018-02-23 19:02       ` Dongwon Kim
2018-04-10  9:52   ` [RFC, v2, " Oleksandr Andrushchenko
2018-04-10  9:52     ` Oleksandr Andrushchenko
2018-04-10  9:52   ` Oleksandr Andrushchenko
2018-02-14  1:50 ` [RFC PATCH v2 " Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 3/9] MAINTAINERS: adding Hyper_DMABUF driver section in MAINTAINERS Dongwon Kim
2018-02-14  1:50 ` Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 4/9] hyper_dmabuf: user private data attached to hyper_DMABUF Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-04-10  9:59   ` [RFC, v2, " Oleksandr Andrushchenko
2018-04-10  9:59     ` Oleksandr Andrushchenko
2018-04-10  9:59   ` Oleksandr Andrushchenko
2018-02-14  1:50 ` Dongwon Kim [this message]
2018-02-14  1:50 ` [RFC PATCH v2 5/9] hyper_dmabuf: default backend for XEN hypervisor Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-04-10  9:27   ` [RFC, v2, " Oleksandr Andrushchenko
2018-04-10  9:27   ` [RFC,v2,5/9] " Oleksandr Andrushchenko
2018-02-14  1:50 ` [RFC PATCH v2 5/9] " Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 6/9] hyper_dmabuf: hyper_DMABUF synchronization across VM Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-02-14  1:50 ` Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 7/9] hyper_dmabuf: query ioctl for retreiving various hyper_DMABUF info Dongwon Kim
2018-02-14  1:50 ` Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 8/9] hyper_dmabuf: event-polling mechanism for detecting a new hyper_DMABUF Dongwon Kim
2018-02-14  1:50 ` Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-02-14  1:50 ` [RFC PATCH v2 9/9] hyper_dmabuf: threaded interrupt in Xen-backend Dongwon Kim
2018-02-14  1:50   ` Dongwon Kim
2018-04-10 10:04   ` [RFC, v2, " Oleksandr Andrushchenko
2018-04-10 10:04   ` [RFC,v2,9/9] " Oleksandr Andrushchenko
2018-02-14  1:50 ` [RFC PATCH v2 9/9] " Dongwon Kim
2018-02-19 17:01 ` [RFC PATCH v2 0/9] hyper_dmabuf: Hyper_DMABUF driver Daniel Vetter
2018-02-19 17:01   ` Daniel Vetter
2018-02-21 20:18   ` Dongwon Kim
2018-02-21 20:18   ` Dongwon Kim
2018-02-21 20:18     ` Dongwon Kim
2018-02-19 17:01 ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='20180214015008.9513-5-dongwon.kim__15246.8656575822$1518573039$gmane$org@intel.com' \
    --to=dongwon.kim@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mateuszx.potrola@intel.com \
    --cc=sumit.semwal@linaro.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.