All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4
@ 2021-07-14  4:14 Zack Rusin
  2021-07-14  4:14 ` [PATCH 2/4] drm/vmwgfx: Switch to using DRM_IOCTL_DEF_DRV Zack Rusin
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Zack Rusin @ 2021-07-14  4:14 UTC (permalink / raw)
  To: dri-devel; +Cc: Martin Krastev

From: Martin Krastev <krastevm@vmware.com>

* Add support for CursorMob
* Add support for CursorBypass 4

Reviewed-by: Zack Rusin <zackr@vmware.com>
Signed-off-by: Martin Krastev <krastevm@vmware.com>
Signed-off-by: Zack Rusin <zackr@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 45 +++++++++++++++-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |  6 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 79 +++++++++++++++++++++++++++--
 3 files changed, 125 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 086dc75e7b42..7d8cc2f6b04e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2016 VMware, Inc., Palo Alto, CA., USA
+ * Copyright 2009-2021 VMware, Inc., Palo Alto, CA., USA
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -301,8 +301,12 @@ static void vmw_print_capabilities2(uint32_t capabilities2)
 		DRM_INFO("  Grow oTable.\n");
 	if (capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY)
 		DRM_INFO("  IntraSurface copy.\n");
+	if (capabilities2 & SVGA_CAP2_CURSOR_MOB)
+		DRM_INFO("  Cursor Mob.\n");
 	if (capabilities2 & SVGA_CAP2_DX3)
 		DRM_INFO("  DX3.\n");
+	if (capabilities2 & SVGA_CAP2_EXTRA_REGS)
+		DRM_INFO("  Extra Regs.\n");
 }
 
 static void vmw_print_capabilities(uint32_t capabilities)
@@ -505,6 +509,7 @@ static int vmw_request_device_late(struct vmw_private *dev_priv)
 static int vmw_request_device(struct vmw_private *dev_priv)
 {
 	int ret;
+	size_t i;
 
 	ret = vmw_device_init(dev_priv);
 	if (unlikely(ret != 0)) {
@@ -526,6 +531,37 @@ static int vmw_request_device(struct vmw_private *dev_priv)
 	if (unlikely(ret != 0))
 		goto out_no_query_bo;
 
+	/* Set up mobs for cursor updates */
+	if (dev_priv->has_mob && dev_priv->capabilities2 & SVGA_CAP2_CURSOR_MOB) {
+		const uint32_t cursor_max_dim = vmw_read(dev_priv, SVGA_REG_CURSOR_MAX_DIMENSION);
+
+		for (i = 0; i < ARRAY_SIZE(dev_priv->cursor_mob); i++) {
+			struct ttm_buffer_object **const bo = &dev_priv->cursor_mob[i];
+
+			ret = vmw_bo_create_kernel(dev_priv,
+				cursor_max_dim * cursor_max_dim * sizeof(u32) + sizeof(SVGAGBCursorHeader),
+				&vmw_mob_placement, bo);
+
+			if (ret != 0) {
+				DRM_ERROR("Unable to create CursorMob array.\n");
+				break;
+			}
+
+			BUG_ON((*bo)->resource->mem_type != VMW_PL_MOB);
+
+			/* Fence the mob creation so we are guarateed to have the mob */
+			ret = ttm_bo_reserve(*bo, false, true, NULL);
+			BUG_ON(ret);
+
+			vmw_bo_fence_single(*bo, NULL);
+
+			ttm_bo_unreserve(*bo);
+
+			DRM_INFO("Using CursorMob mobid %lu, max dimension %u\n",
+				 (*bo)->resource->start, cursor_max_dim);
+		}
+	}
+
 	return 0;
 
 out_no_query_bo:
@@ -556,6 +592,8 @@ static int vmw_request_device(struct vmw_private *dev_priv)
  */
 static void vmw_release_device_early(struct vmw_private *dev_priv)
 {
+	size_t i;
+
 	/*
 	 * Previous destructions should've released
 	 * the pinned bo.
@@ -570,6 +608,11 @@ static void vmw_release_device_early(struct vmw_private *dev_priv)
 	if (dev_priv->has_mob) {
 		struct ttm_resource_manager *man;
 
+		for (i = 0; i < ARRAY_SIZE(dev_priv->cursor_mob); i++) {
+			if (dev_priv->cursor_mob[i] != NULL)
+				ttm_bo_put(dev_priv->cursor_mob[i]);
+		}
+
 		man = ttm_manager_type(&dev_priv->bdev, VMW_PL_MOB);
 		ttm_resource_manager_evict_all(&dev_priv->bdev, man);
 		vmw_otables_takedown(dev_priv);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 356f82c26f59..46bf54f6169a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -642,6 +642,12 @@ struct vmw_private {
 	u8 mksstat_kern_top_timer[MKSSTAT_CAPACITY];
 	atomic_t mksstat_kern_pids[MKSSTAT_CAPACITY];
 #endif
+
+	/*
+	 * CursorMob buffer objects
+	 */
+	struct ttm_buffer_object *cursor_mob[2];
+	atomic_t cursor_mob_idx;
 };
 
 static inline struct vmw_surface *vmw_res_to_srf(struct vmw_resource *res)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 2ddf4932d62c..8d7844354774 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
+ * Copyright 2009-2021 VMware, Inc., Palo Alto, CA., USA
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -53,6 +53,10 @@ void vmw_du_cleanup(struct vmw_display_unit *du)
  * Display Unit Cursor functions
  */
 
+static int vmw_cursor_update_mob(struct vmw_private *dev_priv,
+				 u32 *image, u32 width, u32 height,
+				 u32 hotspotX, u32 hotspotY);
+
 static int vmw_cursor_update_image(struct vmw_private *dev_priv,
 				   u32 *image, u32 width, u32 height,
 				   u32 hotspotX, u32 hotspotY)
@@ -67,6 +71,10 @@ static int vmw_cursor_update_image(struct vmw_private *dev_priv,
 	if (!image)
 		return -EINVAL;
 
+	if (dev_priv->cursor_mob[ARRAY_SIZE(dev_priv->cursor_mob) - 1] != NULL)
+		return vmw_cursor_update_mob(dev_priv, image, width, height,
+					     hotspotX, hotspotY);
+
 	cmd = VMW_CMD_RESERVE(dev_priv, cmd_size);
 	if (unlikely(cmd == NULL))
 		return -ENOMEM;
@@ -87,6 +95,62 @@ static int vmw_cursor_update_image(struct vmw_private *dev_priv,
 	return 0;
 }
 
+static int vmw_cursor_update_mob(struct vmw_private *dev_priv,
+				 u32 *image, u32 width, u32 height,
+				 u32 hotspotX, u32 hotspotY)
+{
+	SVGAGBCursorHeader *header;
+	SVGAGBAlphaCursorHeader *alpha_header;
+	const u32 image_size = width * height * sizeof(*image);
+	const u32 mob_size = sizeof(*header) + image_size;
+
+	struct ttm_buffer_object *bo;
+	struct ttm_bo_kmap_obj map;
+	bool dummy;
+	int ret;
+
+	bo = dev_priv->cursor_mob[atomic_inc_return(&dev_priv->cursor_mob_idx) %
+		ARRAY_SIZE(dev_priv->cursor_mob)];
+	BUG_ON(bo == NULL);
+
+	ret = ttm_bo_reserve(bo, true, false, NULL);
+
+	if (unlikely(ret != 0)) {
+		DRM_ERROR("reserve failed\n");
+		return -EINVAL;
+	}
+
+	ret = ttm_bo_kmap(bo, 0, vmw_num_pages(mob_size), &map);
+
+	if (unlikely(ret != 0))
+		goto err_map;
+
+	header = (SVGAGBCursorHeader *)ttm_kmap_obj_virtual(&map, &dummy);
+	alpha_header = &header->header.alphaHeader;
+
+	header->type = SVGA_ALPHA_CURSOR;
+	header->sizeInBytes = image_size;
+
+	alpha_header->hotspotX = hotspotX;
+	alpha_header->hotspotY = hotspotY;
+	alpha_header->width = width;
+	alpha_header->height = height;
+
+	memcpy(header + 1, image, image_size);
+
+	ttm_bo_kunmap(&map);
+	ttm_bo_unreserve(bo);
+
+	vmw_write(dev_priv, SVGA_REG_CURSOR_MOBID, bo->resource->start);
+
+	return 0;
+
+err_map:
+	ttm_bo_unreserve(bo);
+
+	return ret;
+}
+
 static int vmw_cursor_update_bo(struct vmw_private *dev_priv,
 				struct vmw_buffer_object *bo,
 				u32 width, u32 height,
@@ -127,11 +191,18 @@ static int vmw_cursor_update_bo(struct vmw_private *dev_priv,
 static void vmw_cursor_update_position(struct vmw_private *dev_priv,
 				       bool show, int x, int y)
 {
+	const uint32_t svga_cursor_on = show ? SVGA_CURSOR_ON_SHOW
+					     : SVGA_CURSOR_ON_HIDE;
 	uint32_t count;
 
 	spin_lock(&dev_priv->cursor_lock);
-	if (vmw_is_cursor_bypass3_enabled(dev_priv)) {
-		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, show ? 1 : 0);
+	if (dev_priv->capabilities2 & SVGA_CAP2_EXTRA_REGS) {
+		vmw_write(dev_priv, SVGA_REG_CURSOR4_X, x);
+		vmw_write(dev_priv, SVGA_REG_CURSOR4_Y, y);
+		vmw_write(dev_priv, SVGA_REG_CURSOR4_ON, svga_cursor_on);
+		vmw_write(dev_priv, SVGA_REG_CURSOR4_SUBMIT, TRUE);
+	} else if (vmw_is_cursor_bypass3_enabled(dev_priv)) {
+		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_ON, svga_cursor_on);
 		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_X, x);
 		vmw_fifo_mem_write(dev_priv, SVGA_FIFO_CURSOR_Y, y);
 		count = vmw_fifo_mem_read(dev_priv, SVGA_FIFO_CURSOR_COUNT);
@@ -139,7 +210,7 @@ static void vmw_cursor_update_position(struct vmw_private *dev_priv,
 	} else {
 		vmw_write(dev_priv, SVGA_REG_CURSOR_X, x);
 		vmw_write(dev_priv, SVGA_REG_CURSOR_Y, y);
-		vmw_write(dev_priv, SVGA_REG_CURSOR_ON, show ? 1 : 0);
+		vmw_write(dev_priv, SVGA_REG_CURSOR_ON, svga_cursor_on);
 	}
 	spin_unlock(&dev_priv->cursor_lock);
 }
-- 
2.30.2


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

* [PATCH 2/4] drm/vmwgfx: Switch to using DRM_IOCTL_DEF_DRV
  2021-07-14  4:14 [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Zack Rusin
@ 2021-07-14  4:14 ` Zack Rusin
  2021-07-14  4:14 ` [PATCH 3/4] drm/vmwgfx: Be a lot more flexible with MOB limits Zack Rusin
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Zack Rusin @ 2021-07-14  4:14 UTC (permalink / raw)
  To: dri-devel; +Cc: Martin Krastev

The macro has been accounting for DRM_COMMAND_BASE for a long time
now so there's no reason to still be duplicating it. Plus we were
leaving the name undefined which meant that all the DRM ioctl
warnings/errors were always listing "null" ioctl at the culprit.

This fixes the undefined ioctl name and removes duplicated code.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Martin Krastev <krastevm@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 176 +++++++++++++---------------
 1 file changed, 84 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 7d8cc2f6b04e..359f2e6f3693 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -159,110 +159,102 @@
 	DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_MKSSTAT_REMOVE,	\
 		struct drm_vmw_mksstat_remove_arg)
 
-/*
- * The core DRM version of this macro doesn't account for
- * DRM_COMMAND_BASE.
- */
-
-#define VMW_IOCTL_DEF(ioctl, func, flags) \
-  [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_IOCTL_##ioctl, flags, func}
-
 /*
  * Ioctl definitions.
  */
 
 static const struct drm_ioctl_desc vmw_ioctls[] = {
-	VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_bo_alloc_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_bo_unref_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_CURSOR_BYPASS,
-		      vmw_kms_cursor_bypass_ioctl,
-		      DRM_MASTER),
-
-	VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl,
-		      DRM_MASTER),
-	VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl,
-		      DRM_MASTER),
-	VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl,
-		      DRM_MASTER),
-
-	VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_obj_wait_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_FENCE_SIGNALED,
-		      vmw_fence_obj_signaled_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_FENCE_UNREF, vmw_fence_obj_unref_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_FENCE_EVENT, vmw_fence_event_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl,
-		      DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_GET_PARAM, vmw_getparam_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_ALLOC_DMABUF, vmw_bo_alloc_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_UNREF_DMABUF, vmw_bo_unref_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_CURSOR_BYPASS,
+			  vmw_kms_cursor_bypass_ioctl,
+			  DRM_MASTER),
+
+	DRM_IOCTL_DEF_DRV(VMW_CONTROL_STREAM, vmw_overlay_ioctl,
+			  DRM_MASTER),
+	DRM_IOCTL_DEF_DRV(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl,
+			  DRM_MASTER),
+	DRM_IOCTL_DEF_DRV(VMW_UNREF_STREAM, vmw_stream_unref_ioctl,
+			  DRM_MASTER),
+
+	DRM_IOCTL_DEF_DRV(VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_REF_SURFACE, vmw_surface_reference_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_EXECBUF, vmw_execbuf_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_FENCE_WAIT, vmw_fence_obj_wait_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_FENCE_SIGNALED,
+			  vmw_fence_obj_signaled_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_FENCE_UNREF, vmw_fence_obj_unref_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_FENCE_EVENT, vmw_fence_event_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl,
+			  DRM_RENDER_ALLOW),
 
 	/* these allow direct access to the framebuffers mark as master only */
-	VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl,
-		      DRM_MASTER | DRM_AUTH),
-	VMW_IOCTL_DEF(VMW_PRESENT_READBACK,
-		      vmw_present_readback_ioctl,
-		      DRM_MASTER | DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(VMW_PRESENT, vmw_present_ioctl,
+			  DRM_MASTER | DRM_AUTH),
+	DRM_IOCTL_DEF_DRV(VMW_PRESENT_READBACK,
+			  vmw_present_readback_ioctl,
+			  DRM_MASTER | DRM_AUTH),
 	/*
 	 * The permissions of the below ioctl are overridden in
 	 * vmw_generic_ioctl(). We require either
 	 * DRM_MASTER or capable(CAP_SYS_ADMIN).
 	 */
-	VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT,
-		      vmw_kms_update_layout_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_CREATE_SHADER,
-		      vmw_shader_define_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_UNREF_SHADER,
-		      vmw_shader_destroy_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE,
-		      vmw_gb_surface_define_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_GB_SURFACE_REF,
-		      vmw_gb_surface_reference_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_SYNCCPU,
-		      vmw_user_bo_synccpu_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_CREATE_EXTENDED_CONTEXT,
-		      vmw_extended_context_define_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_GB_SURFACE_CREATE_EXT,
-		      vmw_gb_surface_define_ext_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_GB_SURFACE_REF_EXT,
-		      vmw_gb_surface_reference_ext_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_MSG,
-		      vmw_msg_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_MKSSTAT_RESET,
-		      vmw_mksstat_reset_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_MKSSTAT_ADD,
-		      vmw_mksstat_add_ioctl,
-		      DRM_RENDER_ALLOW),
-	VMW_IOCTL_DEF(VMW_MKSSTAT_REMOVE,
-		      vmw_mksstat_remove_ioctl,
-		      DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_UPDATE_LAYOUT,
+			  vmw_kms_update_layout_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_CREATE_SHADER,
+			  vmw_shader_define_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_UNREF_SHADER,
+			  vmw_shader_destroy_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_GB_SURFACE_CREATE,
+			  vmw_gb_surface_define_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_GB_SURFACE_REF,
+			  vmw_gb_surface_reference_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_SYNCCPU,
+			  vmw_user_bo_synccpu_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_CREATE_EXTENDED_CONTEXT,
+			  vmw_extended_context_define_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_GB_SURFACE_CREATE_EXT,
+			  vmw_gb_surface_define_ext_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_GB_SURFACE_REF_EXT,
+			  vmw_gb_surface_reference_ext_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_MSG,
+			  vmw_msg_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_MKSSTAT_RESET,
+			  vmw_mksstat_reset_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_MKSSTAT_ADD,
+			  vmw_mksstat_add_ioctl,
+			  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(VMW_MKSSTAT_REMOVE,
+			  vmw_mksstat_remove_ioctl,
+			  DRM_RENDER_ALLOW),
 };
 
 static const struct pci_device_id vmw_pci_id_list[] = {
-- 
2.30.2


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

* [PATCH 3/4] drm/vmwgfx: Be a lot more flexible with MOB limits
  2021-07-14  4:14 [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Zack Rusin
  2021-07-14  4:14 ` [PATCH 2/4] drm/vmwgfx: Switch to using DRM_IOCTL_DEF_DRV Zack Rusin
@ 2021-07-14  4:14 ` Zack Rusin
  2021-07-14  4:14 ` [PATCH 4/4] drm/vmwgfx: Use 2.19 version number to recognize mks-stats ioctls Zack Rusin
  2021-07-14  7:30 ` [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Thomas Zimmermann
  3 siblings, 0 replies; 6+ messages in thread
From: Zack Rusin @ 2021-07-14  4:14 UTC (permalink / raw)
  To: dri-devel; +Cc: Martin Krastev

The code was trying to keep a strict limit on the amount of mob
memory that was used in the guest by making it match the host
settings. There's technically no reason to do that (guests can
certainly use more than the host can have resident in renderers
at the same time).

In particular this is problematic because our userspace is not
great at handling OOM conditions and running out of MOB space
results in GL apps crashing, e.g. gnome-shell likes to allocate
huge surfaces (~61MB for the desktop on 2560x1600 with two workspaces)
and running out of memory there means that the gnome-shell crashes
on startup taking us back to the login and resulting in a system
where one can not login in graphically anymore.

Instead of letting the userspace crash we can extend available
MOB space, we just don't want to use all of the RAM for graphics,
so we're going to limit it to half of RAM.

With the addition of some extra logging this should make the
"guest has been configured with not enough graphics memory"
errors a lot easier to diagnose in cases where the automatic
expansion of MOB space fails.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Martin Krastev <krastevm@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c           |  8 ++++-
 drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 36 +++++++++++++++++--
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 359f2e6f3693..a9195c472b75 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -948,6 +948,13 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
 		dev_priv->texture_max_height = 8192;
 		dev_priv->max_primary_mem = dev_priv->vram_size;
 	}
+	DRM_INFO("Legacy memory limits: VRAM = %llu kB, FIFO = %llu kB, surface = %u kB\n",
+		 (u64)dev_priv->vram_size / 1024,
+		 (u64)dev_priv->fifo_mem_size / 1024,
+		 dev_priv->memory_size / 1024);
+
+	DRM_INFO("MOB limits: max mob size = %u kB, max mob pages = %u\n",
+		 dev_priv->max_mob_size / 1024, dev_priv->max_mob_pages);
 
 	vmw_print_capabilities(dev_priv->capabilities);
 	if (dev_priv->capabilities & SVGA_CAP_CAP2_REGISTER)
@@ -1094,7 +1101,6 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id)
 		DRM_INFO("SM4_1 support available.\n");
 	if (dev_priv->sm_type == VMW_SM_4)
 		DRM_INFO("SM4 support available.\n");
-	DRM_INFO("Running without reservation semaphore\n");
 
 	vmw_host_printf("vmwgfx: Module Version: %d.%d.%d (kernel: %s)",
 			VMWGFX_DRIVER_MAJOR, VMWGFX_DRIVER_MINOR,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
index 28ceb749a733..b2c4af331c9d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -71,8 +71,40 @@ static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man,
 
 	if (gman->max_gmr_pages > 0) {
 		gman->used_gmr_pages += (*res)->num_pages;
-		if (unlikely(gman->used_gmr_pages > gman->max_gmr_pages))
-			goto nospace;
+		/*
+		 * Because the graphics memory is a soft limit we can try to
+		 * expand it instead of letting the userspace apps crash.
+		 * We're just going to have a sane limit (half of RAM)
+		 * on the number of MOB's that we create and will try to keep
+		 * the system running until we reach that.
+		 */
+		if (unlikely(gman->used_gmr_pages > gman->max_gmr_pages)) {
+			const unsigned long max_graphics_pages = totalram_pages() / 2;
+			uint32_t new_max_pages = 0;
+
+			DRM_WARN("vmwgfx: mob memory overflow. Consider increasing guest RAM and graphicsMemory.\n");
+			vmw_host_printf("vmwgfx, warning: mob memory overflow. Consider increasing guest RAM and graphicsMemory.\n");
+
+			if (gman->max_gmr_pages > (max_graphics_pages / 2)) {
+				DRM_WARN("vmwgfx: guest requires more than half of RAM for graphics.\n");
+				new_max_pages = max_graphics_pages;
+			} else
+				new_max_pages = gman->max_gmr_pages * 2;
+			if (new_max_pages > gman->max_gmr_pages && new_max_pages >= gman->used_gmr_pages) {
+				DRM_WARN("vmwgfx: increasing guest mob limits to %u kB.\n",
+					 ((new_max_pages) << (PAGE_SHIFT - 10)));
+
+				gman->max_gmr_pages = new_max_pages;
+			} else {
+				char buf[256];
+				snprintf(buf, sizeof(buf),
+					 "vmwgfx, error: guest graphics is out of memory (mob limit at: %ukB).\n",
+					 ((gman->max_gmr_pages) << (PAGE_SHIFT - 10)));
+				vmw_host_printf(buf);
+				DRM_WARN("%s", buf);
+				goto nospace;
+			}
+		}
 	}
 
 	(*res)->start = id;
-- 
2.30.2


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

* [PATCH 4/4] drm/vmwgfx: Use 2.19 version number to recognize mks-stats ioctls
  2021-07-14  4:14 [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Zack Rusin
  2021-07-14  4:14 ` [PATCH 2/4] drm/vmwgfx: Switch to using DRM_IOCTL_DEF_DRV Zack Rusin
  2021-07-14  4:14 ` [PATCH 3/4] drm/vmwgfx: Be a lot more flexible with MOB limits Zack Rusin
@ 2021-07-14  4:14 ` Zack Rusin
  2021-07-14  7:30 ` [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Thomas Zimmermann
  3 siblings, 0 replies; 6+ messages in thread
From: Zack Rusin @ 2021-07-14  4:14 UTC (permalink / raw)
  To: dri-devel; +Cc: Martin Krastev, Reviewed-by : Neha Bhende

To let the userspace recognize that it's running on top of a vmwgfx
that supports mks-stat ioctls we need to bump the version number.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Martin Krastev <krastevm@vmware.com>
Reviewed-by: Reviewed-by: Neha Bhende <bhenden@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 46bf54f6169a..aaadda5f1b4a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -54,10 +54,10 @@
 
 
 #define VMWGFX_DRIVER_NAME "vmwgfx"
-#define VMWGFX_DRIVER_DATE "20210218"
+#define VMWGFX_DRIVER_DATE "20210713"
 #define VMWGFX_DRIVER_MAJOR 2
-#define VMWGFX_DRIVER_MINOR 18
-#define VMWGFX_DRIVER_PATCHLEVEL 1
+#define VMWGFX_DRIVER_MINOR 19
+#define VMWGFX_DRIVER_PATCHLEVEL 0
 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
 #define VMWGFX_MAX_RELOCATIONS 2048
 #define VMWGFX_MAX_VALIDATIONS 2048
-- 
2.30.2


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

* Re: [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4
  2021-07-14  4:14 [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Zack Rusin
                   ` (2 preceding siblings ...)
  2021-07-14  4:14 ` [PATCH 4/4] drm/vmwgfx: Use 2.19 version number to recognize mks-stats ioctls Zack Rusin
@ 2021-07-14  7:30 ` Thomas Zimmermann
  2021-07-22 17:22   ` Zack Rusin
  3 siblings, 1 reply; 6+ messages in thread
From: Thomas Zimmermann @ 2021-07-14  7:30 UTC (permalink / raw)
  To: Zack Rusin, dri-devel; +Cc: Martin Krastev


[-- Attachment #1.1: Type: text/plain, Size: 6124 bytes --]

Hi

Am 14.07.21 um 06:14 schrieb Zack Rusin:
> From: Martin Krastev <krastevm@vmware.com>
> 
> * Add support for CursorMob
> * Add support for CursorBypass 4
> 
> Reviewed-by: Zack Rusin <zackr@vmware.com>
> Signed-off-by: Martin Krastev <krastevm@vmware.com>
> Signed-off-by: Zack Rusin <zackr@vmware.com>
> ---
>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 45 +++++++++++++++-
>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |  6 +++
>   drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 79 +++++++++++++++++++++++++++--
>   3 files changed, 125 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index 086dc75e7b42..7d8cc2f6b04e 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -1,7 +1,7 @@
>   // SPDX-License-Identifier: GPL-2.0 OR MIT
>   /**************************************************************************
>    *
> - * Copyright 2009-2016 VMware, Inc., Palo Alto, CA., USA
> + * Copyright 2009-2021 VMware, Inc., Palo Alto, CA., USA
>    *
>    * Permission is hereby granted, free of charge, to any person obtaining a
>    * copy of this software and associated documentation files (the
> @@ -301,8 +301,12 @@ static void vmw_print_capabilities2(uint32_t capabilities2)
>   		DRM_INFO("  Grow oTable.\n");

These macros have been out of fashion for a while. There's drm_info(), 
drm_warn(), drm_err(), etc as replacements. They also print device 
information. Applis here and for the rest of the patchset.


>   	if (capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY)
>   		DRM_INFO("  IntraSurface copy.\n");
> +	if (capabilities2 & SVGA_CAP2_CURSOR_MOB)
> +		DRM_INFO("  Cursor Mob.\n");
>   	if (capabilities2 & SVGA_CAP2_DX3)
>   		DRM_INFO("  DX3.\n");
> +	if (capabilities2 & SVGA_CAP2_EXTRA_REGS)
> +		DRM_INFO("  Extra Regs.\n");
>   }
>   
>   static void vmw_print_capabilities(uint32_t capabilities)
> @@ -505,6 +509,7 @@ static int vmw_request_device_late(struct vmw_private *dev_priv)
>   static int vmw_request_device(struct vmw_private *dev_priv)
>   {
>   	int ret;
> +	size_t i;
>   
>   	ret = vmw_device_init(dev_priv);
>   	if (unlikely(ret != 0)) {
> @@ -526,6 +531,37 @@ static int vmw_request_device(struct vmw_private *dev_priv)
>   	if (unlikely(ret != 0))
>   		goto out_no_query_bo;
>   
> +	/* Set up mobs for cursor updates */
> +	if (dev_priv->has_mob && dev_priv->capabilities2 & SVGA_CAP2_CURSOR_MOB) {
> +		const uint32_t cursor_max_dim = vmw_read(dev_priv, SVGA_REG_CURSOR_MAX_DIMENSION);
> +
> +		for (i = 0; i < ARRAY_SIZE(dev_priv->cursor_mob); i++) {
> +			struct ttm_buffer_object **const bo = &dev_priv->cursor_mob[i];
> +
> +			ret = vmw_bo_create_kernel(dev_priv,
> +				cursor_max_dim * cursor_max_dim * sizeof(u32) + sizeof(SVGAGBCursorHeader),
> +				&vmw_mob_placement, bo);
> +
> +			if (ret != 0) {
> +				DRM_ERROR("Unable to create CursorMob array.\n");
> +				break;
> +			}
> +
> +			BUG_ON((*bo)->resource->mem_type != VMW_PL_MOB);

BUG_ON() crashes the kernel. The prefered way is to use drm_WARN_*() and 
return.

> +
> +			/* Fence the mob creation so we are guarateed to have the mob */
> +			ret = ttm_bo_reserve(*bo, false, true, NULL);
> +			BUG_ON(ret);

I'm not quite sure, but this line is probably a no-go wrt to best 
practices. See the comment above.

> +
> +			vmw_bo_fence_single(*bo, NULL);
> +
> +			ttm_bo_unreserve(*bo);
> +
> +			DRM_INFO("Using CursorMob mobid %lu, max dimension %u\n",
> +				 (*bo)->resource->start, cursor_max_dim);

IIRC anything *_info() is just radom info into the log. Most of the 
time, no one cares. Better use one of the drm_dbg_() calls.

> +		}
> +	}
> +
>   	return 0;
>   
>   out_no_query_bo:
> @@ -556,6 +592,8 @@ static int vmw_request_device(struct vmw_private *dev_priv)
>    */
>   static void vmw_release_device_early(struct vmw_private *dev_priv)
>   {
> +	size_t i;
> +
>   	/*
>   	 * Previous destructions should've released
>   	 * the pinned bo.
> @@ -570,6 +608,11 @@ static void vmw_release_device_early(struct vmw_private *dev_priv)
>   	if (dev_priv->has_mob) {
>   		struct ttm_resource_manager *man;
>   
> +		for (i = 0; i < ARRAY_SIZE(dev_priv->cursor_mob); i++) {
> +			if (dev_priv->cursor_mob[i] != NULL)
> +				ttm_bo_put(dev_priv->cursor_mob[i]);
> +		}
> +
>   		man = ttm_manager_type(&dev_priv->bdev, VMW_PL_MOB);
>   		ttm_resource_manager_evict_all(&dev_priv->bdev, man);
>   		vmw_otables_takedown(dev_priv);
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> index 356f82c26f59..46bf54f6169a 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
> @@ -642,6 +642,12 @@ struct vmw_private {
>   	u8 mksstat_kern_top_timer[MKSSTAT_CAPACITY];
>   	atomic_t mksstat_kern_pids[MKSSTAT_CAPACITY];
>   #endif
> +
> +	/*
> +	 * CursorMob buffer objects
> +	 */
> +	struct ttm_buffer_object *cursor_mob[2];
> +	atomic_t cursor_mob_idx;

That's something like page-flipping with alternating BO's and shadow 
buffering?

You really want a cursor plane to hold this information.


I briefly looked through vmwgfx and it has all these fail-able code in 
its atomic-update path. The patches here only make things worse. With 
cursor planes, you can do all the preparation in atomic_check and 
prepare_fb, and store the
intermediate state/mappings/etc in the plane state.

The ast driver started with a design like this one here and then we 
moved it to cursor planes. Ast has now none of the mentioned problems. 
Relevant code is at [1][2].

Best regards
Thomas

[1] 
https://elixir.bootlin.com/linux/v5.13.1/source/drivers/gpu/drm/ast/ast_drv.h#L105

[2] 
https://elixir.bootlin.com/linux/v5.13.1/source/drivers/gpu/drm/ast/ast_mode.c#L652

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Felix Imendörffer


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

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

* Re: [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4
  2021-07-14  7:30 ` [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Thomas Zimmermann
@ 2021-07-22 17:22   ` Zack Rusin
  0 siblings, 0 replies; 6+ messages in thread
From: Zack Rusin @ 2021-07-22 17:22 UTC (permalink / raw)
  To: Thomas Zimmermann, dri-devel; +Cc: Martin Krastev

On 7/14/21 3:30 AM, Thomas Zimmermann wrote:
>> @@ -301,8 +301,12 @@ static void vmw_print_capabilities2(uint32_t capabilities2)
>>           DRM_INFO("  Grow oTable.\n");
> 
> These macros have been out of fashion for a while. There's drm_info(), drm_warn(), drm_err(), etc as replacements. They also print device information. Applis here and for the rest of the patchset.

Yea, that's messy, I'll go ahead and cleanup some of our logging in v2.

>> +            BUG_ON((*bo)->resource->mem_type != VMW_PL_MOB);
> 
> BUG_ON() crashes the kernel. The prefered way is to use drm_WARN_*() and return.

This one is really an assert. This should never happen, I'm not sure if it's worth even testing for this because the driver is broken if that happens.

> That's something like page-flipping with alternating BO's and shadow buffering?
> 
> You really want a cursor plane to hold this information.
> 
> 
> I briefly looked through vmwgfx and it has all these fail-able code in its atomic-update path. The patches here only make things worse. With cursor planes, you can do all the preparation in atomic_check and prepare_fb, and store the
> intermediate state/mappings/etc in the plane state.
> 
> The ast driver started with a design like this one here and then we moved it to cursor planes. Ast has now none of the mentioned problems. Relevant code is at [1][2].

Yea, I was hoping to the the cursor mob's first and then go back and refactor the error paths for all cursor modes. I do agree that it's not the cleanest approach because it leaves us in a bit broken state until the refactor lands. I'll take out the cursor mob change from v2 of this patchset to give Martin some time to clean up the patch a bit. I'll probably send that out as a separate "cursor mob and atomic errors refactor/fixes" patchset later.
Thanks for the review!

z

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

end of thread, other threads:[~2021-07-22 17:22 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-14  4:14 [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Zack Rusin
2021-07-14  4:14 ` [PATCH 2/4] drm/vmwgfx: Switch to using DRM_IOCTL_DEF_DRV Zack Rusin
2021-07-14  4:14 ` [PATCH 3/4] drm/vmwgfx: Be a lot more flexible with MOB limits Zack Rusin
2021-07-14  4:14 ` [PATCH 4/4] drm/vmwgfx: Use 2.19 version number to recognize mks-stats ioctls Zack Rusin
2021-07-14  7:30 ` [PATCH 1/4] drm/vmwgfx: Add support for CursorMob and CursorBypass 4 Thomas Zimmermann
2021-07-22 17:22   ` Zack Rusin

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.