public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add RESOURCE_GET_LAYOUT ioctl
@ 2023-11-10  7:16 Julia Zhang
  2023-11-10  7:16 ` [PATCH 1/2] drm/virtio: Implement " Julia Zhang
  2023-11-10  7:16 ` [PATCH 2/2] drm/virtio: Modify " Julia Zhang
  0 siblings, 2 replies; 4+ messages in thread
From: Julia Zhang @ 2023-11-10  7:16 UTC (permalink / raw)
  To: Gurchetan Singh, Chia-I Wu, David Airlie, Gerd Hoffmann,
	linux-kernel, dri-devel, amd-gfx, virtualization
  Cc: Alex Deucher, Christian König, Daniel Vetter, David Airlie,
	Erik Faye-Lund, Marek Olšák, Pierre-Eric Pelloux-Prayer,
	Honglei Huang, Chen Jiqian, Huang Rui, Julia Zhang

This is to add a new ioctl RESOURCE_GET_LAYOUT to virtio-gpu to get the
information about how the host has actually allocated the buffer. It is
implemented to query the stride of linear buffer for dGPU prime on guest VM,
related mesa mr: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23896

Daniel Stone (1):
  drm/virtio: Implement RESOURCE_GET_LAYOUT ioctl

Julia Zhang (1):
  drm/virtio: Modify RESOURCE_GET_LAYOUT ioctl

 drivers/gpu/drm/virtio/virtgpu_drv.c   |  1 +
 drivers/gpu/drm/virtio/virtgpu_drv.h   | 22 ++++++++-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 66 ++++++++++++++++++++++++++
 drivers/gpu/drm/virtio/virtgpu_kms.c   |  8 +++-
 drivers/gpu/drm/virtio/virtgpu_vq.c    | 63 ++++++++++++++++++++++++
 include/uapi/drm/virtgpu_drm.h         | 21 ++++++++
 include/uapi/linux/virtio_gpu.h        | 30 ++++++++++++
 7 files changed, 208 insertions(+), 3 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] drm/virtio: Implement RESOURCE_GET_LAYOUT ioctl
  2023-11-10  7:16 [PATCH 0/2] Add RESOURCE_GET_LAYOUT ioctl Julia Zhang
@ 2023-11-10  7:16 ` Julia Zhang
  2023-11-10  7:16 ` [PATCH 2/2] drm/virtio: Modify " Julia Zhang
  1 sibling, 0 replies; 4+ messages in thread
From: Julia Zhang @ 2023-11-10  7:16 UTC (permalink / raw)
  To: Gurchetan Singh, Chia-I Wu, David Airlie, Gerd Hoffmann,
	linux-kernel, dri-devel, amd-gfx, virtualization
  Cc: Alex Deucher, Christian König, Daniel Vetter, David Airlie,
	Erik Faye-Lund, Marek Olšák, Pierre-Eric Pelloux-Prayer,
	Honglei Huang, Chen Jiqian, Huang Rui, Daniel Stone

From: Daniel Stone <daniels@collabora.com>

This ioctl allows the guest to discover how the guest actually allocated
the underlying buffer, which allows buffers to be used for GL<->Vulkan
interop and through standard window systems. It's also a step towards
properly supporting modifiers in the guest.
---
 drivers/gpu/drm/virtio/virtgpu_drv.c   |  1 +
 drivers/gpu/drm/virtio/virtgpu_drv.h   | 16 +++++-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 71 ++++++++++++++++++++++++++
 drivers/gpu/drm/virtio/virtgpu_kms.c   |  8 ++-
 drivers/gpu/drm/virtio/virtgpu_vq.c    | 56 ++++++++++++++++++++
 include/uapi/drm/virtgpu_drm.h         | 19 +++++++
 include/uapi/linux/virtio_gpu.h        | 30 +++++++++++
 7 files changed, 198 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 4f7140e27614..1ee09974d4b7 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -190,6 +190,7 @@ static unsigned int features[] = {
 	VIRTIO_GPU_F_RESOURCE_BLOB,
 	VIRTIO_GPU_F_CONTEXT_INIT,
 	VIRTIO_GPU_F_CONTEXT_FENCE_WAIT,
+	VIRTIO_GPU_F_RESOURCE_QUERY_LAYOUT,
 };
 static struct virtio_driver virtio_gpu_driver = {
 	.feature_table = features,
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 7ef4b3df0ada..d6fc0d4ecb7d 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -93,6 +93,15 @@ struct virtio_gpu_object {
 	bool host3d_blob, guest_blob;
 	uint32_t blob_mem, blob_flags;
 
+	atomic_t layout_state;
+	struct {
+		uint64_t offset;
+		uint64_t size;
+		uint32_t stride;
+	} planes[VIRTIO_GPU_RES_MAX_PLANES];
+	uint64_t modifier;
+	uint32_t num_planes;
+
 	int uuid_state;
 	uuid_t uuid;
 
@@ -249,6 +258,7 @@ struct virtio_gpu_device {
 	bool has_host_visible;
 	bool has_context_init;
 	bool has_host_fence_wait;
+	bool has_resource_query_layout;
 	struct virtio_shm_region host_visible_region;
 	struct drm_mm host_visible_mm;
 
@@ -281,7 +291,7 @@ struct virtio_gpu_fpriv {
 };
 
 /* virtgpu_ioctl.c */
-#define DRM_VIRTIO_NUM_IOCTLS 12
+#define DRM_VIRTIO_NUM_IOCTLS 13
 extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
 void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file);
 
@@ -436,6 +446,10 @@ int virtio_gpu_cmd_status_freezing(struct virtio_gpu_device *vgdev,
 void virtio_gpu_cmd_host_wait(struct virtio_gpu_device *vgdev,
 			      uint32_t ctx_id, uint64_t fence_id);
 
+int
+virtio_gpu_cmd_get_resource_layout(struct virtio_gpu_device *vgdev,
+				   struct virtio_gpu_object *bo);
+
 /* virtgpu_display.c */
 int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
 void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index b6079d2bff69..51d04460d0d8 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -107,6 +107,9 @@ static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data,
 	case VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs:
 		value = vgdev->capset_id_mask;
 		break;
+	case VIRTGPU_PARAM_RESOURCE_QUERY_LAYOUT:
+		value = vgdev->has_resource_query_layout ? 1 : 0;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -676,6 +679,70 @@ static int virtio_gpu_context_init_ioctl(struct drm_device *dev,
 	return ret;
 }
 
+static int virtio_gpu_resource_query_layout_ioctl(struct drm_device *dev,
+						  void *data,
+						  struct drm_file *file)
+{
+	struct drm_virtgpu_resource_query_layout *args = data;
+	struct virtio_gpu_device *vgdev = dev->dev_private;
+	struct drm_gem_object *obj;
+	struct virtio_gpu_object *bo;
+	int layout_state;
+	int ret = 0;
+	int i;
+
+	if (!vgdev->has_resource_query_layout) {
+		DRM_ERROR("failing: no RQL on host\n");
+		return -EINVAL;
+	}
+
+	obj = drm_gem_object_lookup(file, args->handle);
+	if (obj == NULL) {
+		DRM_ERROR("invalid handle 0x%x\n", args->handle);
+		return -ENOENT;
+	}
+	bo = gem_to_virtio_gpu_obj(obj);
+
+	layout_state = atomic_read(&bo->layout_state);
+	if (layout_state == STATE_ERR) {
+		ret = -EINVAL;
+		goto out;
+	} else if (layout_state == STATE_OK) {
+		goto valid;
+	}
+
+	ret = virtio_gpu_cmd_get_resource_layout(vgdev, bo);
+	if (ret)
+		goto out;
+
+	ret = wait_event_timeout(vgdev->resp_wq,
+				 atomic_read(&bo->layout_state) == STATE_OK,
+				 5 * HZ);
+	if (!ret)
+		goto out;
+
+valid:
+	smp_rmb();
+	WARN_ON(atomic_read(&bo->layout_state) != STATE_OK);
+	args->num_planes = bo->num_planes;
+	args->modifier = bo->modifier;
+	for (i = 0; i < args->num_planes; i++) {
+		args->planes[i].offset = bo->planes[i].offset;
+		args->planes[i].size = bo->planes[i].size;
+		args->planes[i].stride = bo->planes[i].stride;
+	}
+	for (; i < VIRTIO_GPU_MAX_RESOURCE_PLANES; i++) {
+		args->planes[i].offset = 0;
+		args->planes[i].size = 0;
+		args->planes[i].stride = 0;
+	}
+	ret = 0;
+
+out:
+	drm_gem_object_put(obj);
+	return ret;
+}
+
 struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = {
 	DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl,
 			  DRM_RENDER_ALLOW),
@@ -715,4 +782,8 @@ struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = {
 
 	DRM_IOCTL_DEF_DRV(VIRTGPU_CONTEXT_INIT, virtio_gpu_context_init_ioctl,
 			  DRM_RENDER_ALLOW),
+
+	DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_QUERY_LAYOUT,
+			  virtio_gpu_resource_query_layout_ioctl,
+			  DRM_RENDER_ALLOW),
 };
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index dd6450179227..fe863bf07298 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -188,6 +188,9 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
 	if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_BLOB)) {
 		vgdev->has_resource_blob = true;
 	}
+	if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_QUERY_LAYOUT)) {
+		vgdev->has_resource_query_layout = true;
+	}
 	if (virtio_get_shm_region(vgdev->vdev, &vgdev->host_visible_region,
 				  VIRTIO_GPU_SHM_ID_HOST_VISIBLE)) {
 		if (!devm_request_mem_region(&vgdev->vdev->dev,
@@ -221,8 +224,9 @@ int virtio_gpu_init(struct virtio_device *vdev, struct drm_device *dev)
 		 vgdev->has_host_visible ? '+' : '-',
 		 vgdev->has_host_fence_wait ? '+' : '-');
 
-	DRM_INFO("features: %ccontext_init\n",
-		 vgdev->has_context_init ? '+' : '-');
+	DRM_INFO("features: %ccontext_init %cresource_query_layout\n",
+		 vgdev->has_context_init ? '+' : '-',
+		 vgdev->has_resource_query_layout ? '+' : '-');
 
 	ret = virtio_gpu_init_vqs(vdev);
 	if (ret) {
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 7a4c9e30f847..8d0a2eaec11c 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -1333,3 +1333,59 @@ void virtio_gpu_cmd_host_wait(struct virtio_gpu_device *vgdev,
 
 	virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
 }
+
+static void virtio_gpu_cmd_get_resource_layout_cb(struct virtio_gpu_device *vgdev,
+						  struct virtio_gpu_vbuffer *vbuf)
+{
+	struct virtio_gpu_resp_resource_layout *resp =
+		(struct virtio_gpu_resp_resource_layout *)vbuf->resp_buf;
+	struct virtio_gpu_object *bo = vbuf->resp_cb_data;
+	int i;
+
+	vbuf->resp_cb_data = NULL;
+
+	if (resp->hdr.type != VIRTIO_GPU_RESP_OK_RESOURCE_LAYOUT) {
+		atomic_set(&bo->layout_state, STATE_ERR);
+		goto out;
+	}
+
+	bo->modifier = le64_to_cpu(resp->modifier);
+	bo->num_planes = le32_to_cpu(resp->num_planes);
+	for (i = 0; i < VIRTIO_GPU_RES_MAX_PLANES; i++) {
+		bo->planes[i].offset = le64_to_cpu(resp->planes[i].offset);
+		bo->planes[i].size = le64_to_cpu(resp->planes[i].size);
+		bo->planes[i].stride = le32_to_cpu(resp->planes[i].stride);
+	}
+	smp_wmb();
+	atomic_set(&bo->layout_state, STATE_OK);
+
+out:
+	drm_gem_object_put(&bo->base.base);
+	wake_up_all(&vgdev->resp_wq);
+}
+
+int virtio_gpu_cmd_get_resource_layout(struct virtio_gpu_device *vgdev,
+				       struct virtio_gpu_object *bo)
+{
+	struct virtio_gpu_resource_query_layout *cmd_p;
+	struct virtio_gpu_vbuffer *vbuf;
+	void *resp_buf;
+
+	resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_resource_layout),
+			   GFP_KERNEL);
+	if (!resp_buf)
+		return -ENOMEM;
+
+	cmd_p = virtio_gpu_alloc_cmd_resp
+		(vgdev, &virtio_gpu_cmd_get_resource_layout_cb, &vbuf,
+		 sizeof(*cmd_p), sizeof(struct virtio_gpu_resp_resource_layout),
+		 resp_buf);
+	memset(cmd_p, 0, sizeof(*cmd_p));
+
+	cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_QUERY_LAYOUT);
+	cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
+	drm_gem_object_get(&bo->base.base);
+	vbuf->resp_cb_data = bo;
+	virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
+	return 0;
+}
diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h
index ac804cef737c..7ec57d7e261a 100644
--- a/include/uapi/drm/virtgpu_drm.h
+++ b/include/uapi/drm/virtgpu_drm.h
@@ -48,6 +48,7 @@ extern "C" {
 #define DRM_VIRTGPU_GET_CAPS  0x09
 #define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x0a
 #define DRM_VIRTGPU_CONTEXT_INIT 0x0b
+#define DRM_VIRTGPU_RESOURCE_QUERY_LAYOUT 0x0c
 
 #define VIRTGPU_EXECBUF_FENCE_FD_IN	0x01
 #define VIRTGPU_EXECBUF_FENCE_FD_OUT	0x02
@@ -97,6 +98,7 @@ struct drm_virtgpu_execbuffer {
 #define VIRTGPU_PARAM_CROSS_DEVICE 5 /* Cross virtio-device resource sharing  */
 #define VIRTGPU_PARAM_CONTEXT_INIT 6 /* DRM_VIRTGPU_CONTEXT_INIT */
 #define VIRTGPU_PARAM_SUPPORTED_CAPSET_IDs 7 /* Bitmask of supported capability set ids */
+#define VIRTGPU_PARAM_RESOURCE_QUERY_LAYOUT 8 /* DRM_VIRTGPU_RESOURCE_QUERY_LAYOUT (also needs cap) */
 
 struct drm_virtgpu_getparam {
 	__u64 param;
@@ -212,6 +214,19 @@ struct drm_virtgpu_context_init {
 	__u64 ctx_set_params;
 };
 
+#define VIRTIO_GPU_MAX_RESOURCE_PLANES 4
+struct drm_virtgpu_resource_query_layout {
+	__u32 handle;
+	__u32 num_planes;
+	__u64 modifier;
+	struct {
+		__u64 offset;
+		__u64 size;
+		__u32 stride;
+		__u32 padding;
+	} planes[VIRTIO_GPU_MAX_RESOURCE_PLANES];
+};
+
 /*
  * Event code that's given when VIRTGPU_CONTEXT_PARAM_POLL_RINGS_MASK is in
  * effect.  The event size is sizeof(drm_event), since there is no additional
@@ -262,6 +277,10 @@ struct drm_virtgpu_context_init {
 	DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_CONTEXT_INIT,		\
 		struct drm_virtgpu_context_init)
 
+#define DRM_IOCTL_VIRTGPU_RESOURCE_QUERY_LAYOUT				\
+	DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRTGPU_RESOURCE_QUERY_LAYOUT,	\
+		struct drm_virtgpu_resource_query_layout)
+
 #if defined(__cplusplus)
 }
 #endif
diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h
index c9bf921303cc..c7b22861af69 100644
--- a/include/uapi/linux/virtio_gpu.h
+++ b/include/uapi/linux/virtio_gpu.h
@@ -70,6 +70,11 @@
  */
 #define VIRTIO_GPU_F_CONTEXT_FENCE_WAIT  5
 
+/*
+ * VIRTIO_GPU_CMD_RESOURCE_QUERY_LAYOUT
+ */
+#define VIRTIO_GPU_F_RESOURCE_QUERY_LAYOUT 6
+
 enum virtio_gpu_ctrl_type {
 	VIRTIO_GPU_UNDEFINED = 0,
 
@@ -101,6 +106,7 @@ enum virtio_gpu_ctrl_type {
 	VIRTIO_GPU_CMD_RESOURCE_MAP_BLOB,
 	VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB,
 	VIRTIO_GPU_CMD_WAIT_FENCE,
+	VIRTIO_GPU_CMD_RESOURCE_QUERY_LAYOUT,
 
 	/* cursor commands */
 	VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300,
@@ -114,6 +120,7 @@ enum virtio_gpu_ctrl_type {
 	VIRTIO_GPU_RESP_OK_EDID,
 	VIRTIO_GPU_RESP_OK_RESOURCE_UUID,
 	VIRTIO_GPU_RESP_OK_MAP_INFO,
+	VIRTIO_GPU_RESP_OK_RESOURCE_LAYOUT,
 
 	/* error responses */
 	VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200,
@@ -474,4 +481,27 @@ struct virtio_gpu_cmd_host_wait {
 	__le64 fence_id;
 };
 
+/* VIRTIO_GPU_CMD_RESOURCE_QUERY_LAYOUT */
+struct virtio_gpu_resource_query_layout {
+	struct virtio_gpu_ctrl_hdr hdr;
+	__le32 resource_id;
+	__le32 padding;
+};
+
+
+/* VIRTIO_GPU_RESP_OK_RESOURCE_LAYOUT */
+#define VIRTIO_GPU_RES_MAX_PLANES 4
+struct virtio_gpu_resp_resource_layout {
+	struct virtio_gpu_ctrl_hdr hdr;
+	__le64 modifier;
+	__le32 num_planes;
+	__le32 padding;
+	struct virtio_gpu_resource_plane {
+		__le64 offset;
+		__le64 size;
+		__le32 stride;
+		__le32 padding;
+	} planes[VIRTIO_GPU_RES_MAX_PLANES];
+};
+
 #endif
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] drm/virtio: Modify RESOURCE_GET_LAYOUT ioctl
  2023-11-10  7:16 [PATCH 0/2] Add RESOURCE_GET_LAYOUT ioctl Julia Zhang
  2023-11-10  7:16 ` [PATCH 1/2] drm/virtio: Implement " Julia Zhang
@ 2023-11-10  7:16 ` Julia Zhang
  2023-11-13 13:18   ` Dmitry Osipenko
  1 sibling, 1 reply; 4+ messages in thread
From: Julia Zhang @ 2023-11-10  7:16 UTC (permalink / raw)
  To: Gurchetan Singh, Chia-I Wu, David Airlie, Gerd Hoffmann,
	linux-kernel, dri-devel, amd-gfx, virtualization
  Cc: Alex Deucher, Christian König, Daniel Vetter, David Airlie,
	Erik Faye-Lund, Marek Olšák, Pierre-Eric Pelloux-Prayer,
	Honglei Huang, Chen Jiqian, Huang Rui, Julia Zhang

Modify RESOURCE_GET_LAYOUT ioctl to handle the use case that query
correct stride for guest linear resource before it is created.

Signed-off-by: Julia Zhang <julia.zhang@amd.com>
---
 drivers/gpu/drm/virtio/virtgpu_drv.h   | 26 ++++++++------
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 47 ++++++++++++--------------
 drivers/gpu/drm/virtio/virtgpu_vq.c    | 35 +++++++++++--------
 include/uapi/drm/virtgpu_drm.h         |  6 ++--
 include/uapi/linux/virtio_gpu.h        |  8 ++---
 5 files changed, 66 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index d6fc0d4ecb7d..82dffb3e4c6b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -93,15 +93,6 @@ struct virtio_gpu_object {
 	bool host3d_blob, guest_blob;
 	uint32_t blob_mem, blob_flags;
 
-	atomic_t layout_state;
-	struct {
-		uint64_t offset;
-		uint64_t size;
-		uint32_t stride;
-	} planes[VIRTIO_GPU_RES_MAX_PLANES];
-	uint64_t modifier;
-	uint32_t num_planes;
-
 	int uuid_state;
 	uuid_t uuid;
 
@@ -225,6 +216,16 @@ struct virtio_gpu_drv_cap_cache {
 	atomic_t is_valid;
 };
 
+struct virtio_gpu_query_info {
+	uint32_t num_planes;
+	uint64_t modifier;
+	struct {
+		uint64_t offset;
+		uint32_t stride;
+	} planes [VIRTIO_GPU_MAX_RESOURCE_PLANES];
+	atomic_t is_valid;
+};
+
 struct virtio_gpu_device {
 	struct drm_device *ddev;
 
@@ -448,7 +449,12 @@ void virtio_gpu_cmd_host_wait(struct virtio_gpu_device *vgdev,
 
 int
 virtio_gpu_cmd_get_resource_layout(struct virtio_gpu_device *vgdev,
-				   struct virtio_gpu_object *bo);
+				   struct virtio_gpu_query_info *bo_info,
+				   uint32_t width,
+				   uint32_t height,
+				   uint32_t format,
+				   uint32_t bind,
+				   uint32_t hw_res_handle);
 
 /* virtgpu_display.c */
 int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 51d04460d0d8..034a7c0927a5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -685,9 +685,9 @@ static int virtio_gpu_resource_query_layout_ioctl(struct drm_device *dev,
 {
 	struct drm_virtgpu_resource_query_layout *args = data;
 	struct virtio_gpu_device *vgdev = dev->dev_private;
-	struct drm_gem_object *obj;
-	struct virtio_gpu_object *bo;
-	int layout_state;
+	struct drm_gem_object *obj = NULL;
+	struct virtio_gpu_object *bo = NULL;
+	struct virtio_gpu_query_info bo_info = {0};
 	int ret = 0;
 	int i;
 
@@ -696,50 +696,45 @@ static int virtio_gpu_resource_query_layout_ioctl(struct drm_device *dev,
 		return -EINVAL;
 	}
 
-	obj = drm_gem_object_lookup(file, args->handle);
-	if (obj == NULL) {
-		DRM_ERROR("invalid handle 0x%x\n", args->handle);
-		return -ENOENT;
-	}
-	bo = gem_to_virtio_gpu_obj(obj);
-
-	layout_state = atomic_read(&bo->layout_state);
-	if (layout_state == STATE_ERR) {
-		ret = -EINVAL;
-		goto out;
-	} else if (layout_state == STATE_OK) {
-		goto valid;
+	if (args->handle > 0) {
+		obj = drm_gem_object_lookup(file, args->handle);
+		if (obj == NULL) {
+			DRM_ERROR("invalid handle 0x%x\n", args->handle);
+			return -ENOENT;
+		}
+		bo = gem_to_virtio_gpu_obj(obj);
 	}
 
-	ret = virtio_gpu_cmd_get_resource_layout(vgdev, bo);
+	ret = virtio_gpu_cmd_get_resource_layout(vgdev, &bo_info, args->width,
+						 args->height, args->format,
+						 args->bind, bo ? bo->hw_res_handle : 0);
 	if (ret)
 		goto out;
 
 	ret = wait_event_timeout(vgdev->resp_wq,
-				 atomic_read(&bo->layout_state) == STATE_OK,
+				 atomic_read(&bo_info.is_valid),
 				 5 * HZ);
 	if (!ret)
 		goto out;
 
 valid:
 	smp_rmb();
-	WARN_ON(atomic_read(&bo->layout_state) != STATE_OK);
-	args->num_planes = bo->num_planes;
-	args->modifier = bo->modifier;
+	WARN_ON(atomic_read(&bo_info.is_valid));
+	args->num_planes = bo_info.num_planes;
+	args->modifier = bo_info.modifier;
 	for (i = 0; i < args->num_planes; i++) {
-		args->planes[i].offset = bo->planes[i].offset;
-		args->planes[i].size = bo->planes[i].size;
-		args->planes[i].stride = bo->planes[i].stride;
+		args->planes[i].offset = bo_info.planes[i].offset;
+		args->planes[i].stride = bo_info.planes[i].stride;
 	}
 	for (; i < VIRTIO_GPU_MAX_RESOURCE_PLANES; i++) {
 		args->planes[i].offset = 0;
-		args->planes[i].size = 0;
 		args->planes[i].stride = 0;
 	}
 	ret = 0;
 
 out:
-	drm_gem_object_put(obj);
+	if (obj)
+		drm_gem_object_put(obj);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 8d0a2eaec11c..95da6d0008f8 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -1339,33 +1339,36 @@ static void virtio_gpu_cmd_get_resource_layout_cb(struct virtio_gpu_device *vgde
 {
 	struct virtio_gpu_resp_resource_layout *resp =
 		(struct virtio_gpu_resp_resource_layout *)vbuf->resp_buf;
-	struct virtio_gpu_object *bo = vbuf->resp_cb_data;
+	struct virtio_gpu_query_info *bo_info = vbuf->resp_cb_data;
 	int i;
 
 	vbuf->resp_cb_data = NULL;
 
 	if (resp->hdr.type != VIRTIO_GPU_RESP_OK_RESOURCE_LAYOUT) {
-		atomic_set(&bo->layout_state, STATE_ERR);
+		atomic_set(&bo_info->is_valid, 0);
 		goto out;
 	}
 
-	bo->modifier = le64_to_cpu(resp->modifier);
-	bo->num_planes = le32_to_cpu(resp->num_planes);
-	for (i = 0; i < VIRTIO_GPU_RES_MAX_PLANES; i++) {
-		bo->planes[i].offset = le64_to_cpu(resp->planes[i].offset);
-		bo->planes[i].size = le64_to_cpu(resp->planes[i].size);
-		bo->planes[i].stride = le32_to_cpu(resp->planes[i].stride);
+	bo_info->modifier = le64_to_cpu(resp->modifier);
+	bo_info->num_planes = le32_to_cpu(resp->num_planes);
+	for (i = 0; i < bo_info->num_planes; i++) {
+		bo_info->planes[i].stride = le32_to_cpu(resp->planes[i].stride);
+		bo_info->planes[i].offset = le32_to_cpu(resp->planes[i].offset);
 	}
 	smp_wmb();
-	atomic_set(&bo->layout_state, STATE_OK);
+	atomic_set(&bo_info->is_valid, 1);
 
 out:
-	drm_gem_object_put(&bo->base.base);
 	wake_up_all(&vgdev->resp_wq);
 }
 
 int virtio_gpu_cmd_get_resource_layout(struct virtio_gpu_device *vgdev,
-				       struct virtio_gpu_object *bo)
+				       struct virtio_gpu_query_info *bo_info,
+				       uint32_t width,
+				       uint32_t height,
+				       uint32_t format,
+				       uint32_t bind,
+				       uint32_t hw_res_handle)
 {
 	struct virtio_gpu_resource_query_layout *cmd_p;
 	struct virtio_gpu_vbuffer *vbuf;
@@ -1383,9 +1386,13 @@ int virtio_gpu_cmd_get_resource_layout(struct virtio_gpu_device *vgdev,
 	memset(cmd_p, 0, sizeof(*cmd_p));
 
 	cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_QUERY_LAYOUT);
-	cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
-	drm_gem_object_get(&bo->base.base);
-	vbuf->resp_cb_data = bo;
+	cmd_p->resource_id = cpu_to_le32(hw_res_handle);
+	cmd_p->width = cpu_to_le32(width);
+	cmd_p->height = cpu_to_le32(height);
+	cmd_p->format = cpu_to_le32(format);
+	cmd_p->bind = cpu_to_le32(bind);
+	vbuf->resp_cb_data = bo_info;
+
 	virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
 	return 0;
 }
diff --git a/include/uapi/drm/virtgpu_drm.h b/include/uapi/drm/virtgpu_drm.h
index 7ec57d7e261a..41f9c592aeaf 100644
--- a/include/uapi/drm/virtgpu_drm.h
+++ b/include/uapi/drm/virtgpu_drm.h
@@ -217,13 +217,15 @@ struct drm_virtgpu_context_init {
 #define VIRTIO_GPU_MAX_RESOURCE_PLANES 4
 struct drm_virtgpu_resource_query_layout {
 	__u32 handle;
+	__u32 width;
+	__u32 height;
+	__u32 format;
+	__u32 bind;
 	__u32 num_planes;
 	__u64 modifier;
 	struct {
 		__u64 offset;
-		__u64 size;
 		__u32 stride;
-		__u32 padding;
 	} planes[VIRTIO_GPU_MAX_RESOURCE_PLANES];
 };
 
diff --git a/include/uapi/linux/virtio_gpu.h b/include/uapi/linux/virtio_gpu.h
index c7b22861af69..3e653f018dd7 100644
--- a/include/uapi/linux/virtio_gpu.h
+++ b/include/uapi/linux/virtio_gpu.h
@@ -485,7 +485,10 @@ struct virtio_gpu_cmd_host_wait {
 struct virtio_gpu_resource_query_layout {
 	struct virtio_gpu_ctrl_hdr hdr;
 	__le32 resource_id;
-	__le32 padding;
+	__le32 width;
+	__le32 height;
+	__le32 format;
+	__le32 bind;
 };
 
 
@@ -495,12 +498,9 @@ struct virtio_gpu_resp_resource_layout {
 	struct virtio_gpu_ctrl_hdr hdr;
 	__le64 modifier;
 	__le32 num_planes;
-	__le32 padding;
 	struct virtio_gpu_resource_plane {
 		__le64 offset;
-		__le64 size;
 		__le32 stride;
-		__le32 padding;
 	} planes[VIRTIO_GPU_RES_MAX_PLANES];
 };
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] drm/virtio: Modify RESOURCE_GET_LAYOUT ioctl
  2023-11-10  7:16 ` [PATCH 2/2] drm/virtio: Modify " Julia Zhang
@ 2023-11-13 13:18   ` Dmitry Osipenko
  0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2023-11-13 13:18 UTC (permalink / raw)
  To: Julia Zhang, Gurchetan Singh, Chia-I Wu, David Airlie,
	Gerd Hoffmann, linux-kernel, dri-devel, amd-gfx, virtualization
  Cc: Pierre-Eric Pelloux-Prayer, Erik Faye-Lund, Marek Olšák,
	Chen Jiqian, Huang Rui, Honglei Huang, Alex Deucher,
	Christian König

On 11/10/23 10:16, Julia Zhang wrote:
> Modify RESOURCE_GET_LAYOUT ioctl to handle the use case that query
> correct stride for guest linear resource before it is created.
> 
> Signed-off-by: Julia Zhang <julia.zhang@amd.com>
> ---
>  drivers/gpu/drm/virtio/virtgpu_drv.h   | 26 ++++++++------
>  drivers/gpu/drm/virtio/virtgpu_ioctl.c | 47 ++++++++++++--------------
>  drivers/gpu/drm/virtio/virtgpu_vq.c    | 35 +++++++++++--------
>  include/uapi/drm/virtgpu_drm.h         |  6 ++--
>  include/uapi/linux/virtio_gpu.h        |  8 ++---
>  5 files changed, 66 insertions(+), 56 deletions(-)

1. Please squash this all into a single patch. For upstream kernel it's
not acceptable to have subsequent commits modifying previous commits. To
commit message add your s-o-b, your co-developed-by tags and a brief
comment explaining changes you've done to the original patch.

Signed-off-by: Daniel Stone <daniels@collabora.com>
Co-developed-by: Julia Zhang <julia.zhang@amd.com> # query correct
stride for guest linear resource before it's created
Signed-off-by: Julia Zhang <julia.zhang@amd.com>

2. Make sure that patch passes `scripts/checkpatch.pl`

3. Add link to the commit message for the relevant Mesa MR that makes
use of the new ioctl. The MR should be already merged or ready to be merged.

Link: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/123456

-- 
Best regards,
Dmitry


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-11-13 13:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-10  7:16 [PATCH 0/2] Add RESOURCE_GET_LAYOUT ioctl Julia Zhang
2023-11-10  7:16 ` [PATCH 1/2] drm/virtio: Implement " Julia Zhang
2023-11-10  7:16 ` [PATCH 2/2] drm/virtio: Modify " Julia Zhang
2023-11-13 13:18   ` Dmitry Osipenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox