[PATCH qxl] Dynamically adjust chunk size to avoid command buffer overflow.

David Mansfield spice at dm.cobite.com
Wed Jun 4 06:13:21 PDT 2014


The maximum number of "commands" that can be queued at once is
fixed at compile time at MAX_RELOCS. However, during the creation
of an image object in qxl_image_create(), the image is split into
commands of maximum size 512*512. For a large dual-head system,
it is easy to create an image for which the number of chunks will
result in an overflow of MAX_RELOCS number of "commands".

Identify this scenario and dynamically increase the chunk size to
avoid the overflow, and the resulting assert() which crashes Xorg.

Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=79317
Signed-off-by: David Mansfield <spice at dm.cobite.com>
---
 src/qxl_image.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/qxl_image.c b/src/qxl_image.c
index 0a0ca30..396aa0f 100644
--- a/src/qxl_image.c
+++ b/src/qxl_image.c
@@ -140,6 +140,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 	struct qxl_bo *image_bo;
 	int dest_stride = (width * Bpp + 3) & (~3);
 	int h;
+	int chunk_size;
 
 	data += y * stride + x * Bpp;
 
@@ -155,9 +156,23 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data,
 
 	hash = 0;
 	h = height;
+
+	chunk_size = MAX (512 * 512, dest_stride);
+
+	/* ensure we will not create too many pieces and overflow
+	 * the command buffer (MAX_RELOCS).  if so, increase the chunk_size.
+	 * each loop creates at least 2 cmd buffer entries, and 
+	 * we have to leave room when we're done.
+	 */
+	if (height / (chunk_size / dest_stride) > (MAX_RELOCS / 4)) {
+		chunk_size = height / (MAX_RELOCS/4) * dest_stride;
+#if 0
+		ErrorF ("adjusted chunk_size to %d\n", chunk_size);
+#endif
+	}
+
 	while (h)
 	{
-	    int chunk_size = MAX (512 * 512, dest_stride);
 	    int n_lines = MIN ((chunk_size / dest_stride), h);
 	    struct qxl_bo *bo = qxl->bo_funcs->bo_alloc (qxl, sizeof (QXLDataChunk) + n_lines * dest_stride, "image data");
 
-- 
1.9.0



More information about the xorg-devel mailing list