dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Hellstrom <thellstrom@vmware.com>
To: dri-devel@lists.freedesktop.org
Subject: [PATCH 18/28] drm/vmwgfx: Avoid cmdbuf alloc sleeping if !TASK_RUNNING
Date: Wed, 12 Aug 2015 22:43:07 -0700	[thread overview]
Message-ID: <1439444597-4664-19-git-send-email-thellstrom@vmware.com> (raw)
In-Reply-To: <1439444597-4664-1-git-send-email-thellstrom@vmware.com>

If the command buffer pool is out of space, the code waits until space is
available. However since the condition code tries to allocate a range manager
node while !TASK_RUNNING we get a kernel warning.

Avoid this by pre-allocating the mm node. This will also probably be more
efficient.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c | 83 ++++++++++++++--------------------
 1 file changed, 34 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
index b044bf5..e94feb3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
@@ -33,7 +33,8 @@
  * multiple of the DMA pool allocation size.
  */
 #define VMW_CMDBUF_INLINE_ALIGN 64
-#define VMW_CMDBUF_INLINE_SIZE (1024 - VMW_CMDBUF_INLINE_ALIGN)
+#define VMW_CMDBUF_INLINE_SIZE \
+	(1024 - ALIGN(sizeof(SVGACBHeader), VMW_CMDBUF_INLINE_ALIGN))
 
 /**
  * struct vmw_cmdbuf_context - Command buffer context queues
@@ -145,7 +146,7 @@ struct vmw_cmdbuf_header {
 	SVGACBHeader *cb_header;
 	SVGACBContext cb_context;
 	struct list_head list;
-	struct drm_mm_node *node;
+	struct drm_mm_node node;
 	dma_addr_t handle;
 	u8 *cmd;
 	size_t size;
@@ -169,13 +170,13 @@ struct vmw_cmdbuf_dheader {
  * struct vmw_cmdbuf_alloc_info - Command buffer space allocation metadata
  *
  * @page_size: Size of requested command buffer space in pages.
- * @node: The range manager node if allocation succeeded.
- * @ret: Error code if failure. Otherwise 0.
+ * @node: Pointer to the range manager node.
+ * @done: True if this allocation has succeeded.
  */
 struct vmw_cmdbuf_alloc_info {
 	size_t page_size;
 	struct drm_mm_node *node;
-	int ret;
+	bool done;
 };
 
 /* Loop over each context in the command buffer manager. */
@@ -253,9 +254,7 @@ static void __vmw_cmdbuf_header_free(struct vmw_cmdbuf_header *header)
 		return;
 	}
 
-	drm_mm_remove_node(header->node);
-	kfree(header->node);
-	header->node = NULL;
+	drm_mm_remove_node(&header->node);
 	wake_up_all(&man->alloc_queue);
 	if (header->cb_header)
 		dma_pool_free(man->headers, header->cb_header,
@@ -669,32 +668,26 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man,
 {
 	int ret;
 
-	if (info->node)
+	if (info->done)
 		return true;
-
-	info->node = kzalloc(sizeof(*info->node), GFP_KERNEL);
-	if (!info->node) {
-		info->ret = -ENOMEM;
-		return true;
-	}
-
+ 
+	memset(info->node, 0, sizeof(*info->node));
 	spin_lock_bh(&man->lock);
-	ret = drm_mm_insert_node_generic(&man->mm, info->node, info->page_size, 0, 0,
+	ret = drm_mm_insert_node_generic(&man->mm, info->node, info->page_size,
+					 0, 0,
 					 DRM_MM_SEARCH_DEFAULT,
 					 DRM_MM_CREATE_DEFAULT);
 	spin_unlock_bh(&man->lock);
-	if (ret) {
-		kfree(info->node);
-		info->node = NULL;
-	}
+	info->done = !ret;
 
-	return !!info->node;
+	return info->done;
 }
 
 /**
  * vmw_cmdbuf_alloc_space - Allocate buffer space from the main pool.
  *
  * @man: The command buffer manager.
+ * @node: Pointer to pre-allocated range-manager node.
  * @size: The size of the allocation.
  * @interruptible: Whether to sleep interruptible while waiting for space.
  *
@@ -702,15 +695,16 @@ static bool vmw_cmdbuf_try_alloc(struct vmw_cmdbuf_man *man,
  * no space available ATM, it turns on IRQ handling and sleeps waiting for it to
  * become available.
  */
-static struct drm_mm_node *vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man,
-						  size_t size,
-						  bool interruptible)
+int vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man,
+			   struct drm_mm_node *node,
+			   size_t size,
+			   bool interruptible)
 {
 	struct vmw_cmdbuf_alloc_info info;
 
 	info.page_size = PAGE_ALIGN(size) >> PAGE_SHIFT;
-	info.node = NULL;
-	info.ret = 0;
+	info.node = node;
+	info.done = false;
 
 	/*
 	 * To prevent starvation of large requests, only one allocating call
@@ -718,22 +712,14 @@ static struct drm_mm_node *vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man,
 	 */
 	if (interruptible) {
 		if (mutex_lock_interruptible(&man->space_mutex))
-			return ERR_PTR(-ERESTARTSYS);
+			return -ERESTARTSYS;
 	} else {
 		mutex_lock(&man->space_mutex);
 	}
 
 	/* Try to allocate space without waiting. */
-	(void) vmw_cmdbuf_try_alloc(man, &info);
-	if (info.ret && !info.node) {
-		mutex_unlock(&man->space_mutex);
-		return ERR_PTR(info.ret);
-	}
-
-	if (info.node) {
-		mutex_unlock(&man->space_mutex);
-		return info.node;
-	}
+	if (vmw_cmdbuf_try_alloc(man, &info))
+		goto out_unlock;
 
 	vmw_generic_waiter_add(man->dev_priv,
 			       SVGA_IRQFLAG_COMMAND_BUFFER,
@@ -749,7 +735,7 @@ static struct drm_mm_node *vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man,
 				(man->dev_priv, SVGA_IRQFLAG_COMMAND_BUFFER,
 				 &man->dev_priv->cmdbuf_waiters);
 			mutex_unlock(&man->space_mutex);
-			return ERR_PTR(ret);
+			return ret;
 		}
 	} else {
 		wait_event(man->alloc_queue, vmw_cmdbuf_try_alloc(man, &info));
@@ -757,11 +743,11 @@ static struct drm_mm_node *vmw_cmdbuf_alloc_space(struct vmw_cmdbuf_man *man,
 	vmw_generic_waiter_remove(man->dev_priv,
 				  SVGA_IRQFLAG_COMMAND_BUFFER,
 				  &man->dev_priv->cmdbuf_waiters);
+
+out_unlock:
 	mutex_unlock(&man->space_mutex);
-	if (info.ret && !info.node)
-		return ERR_PTR(info.ret);
 
-	return info.node;
+	return 0;
 }
 
 /**
@@ -785,10 +771,10 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man,
 	if (!man->has_pool)
 		return -ENOMEM;
 
-	header->node = vmw_cmdbuf_alloc_space(man, size, interruptible);
+	ret = vmw_cmdbuf_alloc_space(man, &header->node,  size, interruptible);
 
-	if (IS_ERR(header->node))
-		return PTR_ERR(header->node);
+	if (ret)
+		return ret;
 
 	header->cb_header = dma_pool_alloc(man->headers, GFP_KERNEL,
 					   &header->handle);
@@ -797,9 +783,9 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man,
 		goto out_no_cb_header;
 	}
 
-	header->size = header->node->size << PAGE_SHIFT;
+	header->size = header->node.size << PAGE_SHIFT;
 	cb_hdr = header->cb_header;
-	offset = header->node->start << PAGE_SHIFT;
+	offset = header->node.start << PAGE_SHIFT;
 	header->cmd = man->map + offset;
 	memset(cb_hdr, 0, sizeof(*cb_hdr));
 	if (man->using_mob) {
@@ -814,9 +800,8 @@ static int vmw_cmdbuf_space_pool(struct vmw_cmdbuf_man *man,
 
 out_no_cb_header:
 	spin_lock_bh(&man->lock);
-	drm_mm_remove_node(header->node);
+	drm_mm_remove_node(&header->node);
 	spin_unlock_bh(&man->lock);
-	kfree(header->node);
 
 	return ret;
 }
-- 
2.1.0


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2015-08-13  6:03 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-13  5:42 [PATCH 00/28] vmwgfx preparation for GL3 Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 01/28] drm/vmwgfx: Fix an fb unlocking bug Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 02/28] vmwgfx: Rework device initialization Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 03/28] drm/vmwgfx: Fix OTABLE takedown Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 04/28] vmwgfx: Update device headers for command buffers Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 05/28] drm/vmwgfx: Add command buffer support v3 Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 06/28] drm/vmwgfx: Fix an overlay lockdep error Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 07/28] drm/vmwgfx: Add an interface to pin a resource v3 Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 08/28] drm/vmwgfx: SVGA device definition update Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 09/28] drm/vmwgfx: Refactor vmw_gb_surface_define_ioctl() Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 10/28] vmwgfx: Major KMS refactoring / cleanup in preparation of screen targets Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 11/28] drm/vmwgfx: Add "quirk" to handling command verification exceptions Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 12/28] drm/vmwgfx: Implement screen targets Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 13/28] drm/vmwgfx: Replace SurfaceDMA usage with SurfaceCopy in 2D VMs Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 14/28] drm/vmwgfx: Introduce a pin count to allow for recursive pinning v2 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 15/28] drm/vmwgfx: Add kms helpers for dirty- and readback functions Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 16/28] drm/vmwgfx: Convert screen objects to the new helpers Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 17/28] drm/vmwgfx: Convert screen targets to new helpers v3 Thomas Hellstrom
2015-08-13  5:43 ` Thomas Hellstrom [this message]
2015-08-13  5:43 ` [PATCH 19/28] drm/vmwgfx: Add a kernel interface to create a framebuffer v2 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 20/28] drm/vmwgfx: Implement fbdev on kms v2 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 21/28] drm/vmwgfx: Reinstate the legacy display system dirty callback Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 22/28] drm/vmwgfx: Fix kms preferred mode sorting Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 23/28] drm/vmwgfx: Kill a bunch of sparse warnings Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 24/28] drm/vmwgfx: Fix compiler warning with 32-bit dma_addr_t Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 25/28] drm/vmwgfx: Fix an uninitialized value Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 26/28] drm/vmwgfx: Fixed topology boundary checking for Screen Targets Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 27/28] drm/vmwgfx: Fix framebuffer creation on older hardware Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 28/28] drm/vmwgfx: Fix crash when unloading vmwgfx v2 Thomas Hellstrom

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=1439444597-4664-19-git-send-email-thellstrom@vmware.com \
    --to=thellstrom@vmware.com \
    --cc=dri-devel@lists.freedesktop.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox