Mesa (master): virgl: Avoid unfinished transfer_get with PIPE_TRANSFER_DONTBLOCK

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Jun 8 04:55:13 UTC 2019


Module: Mesa
Branch: master
Commit: f38cdaebac79788e353b1589f0c0b722f5bc5191
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f38cdaebac79788e353b1589f0c0b722f5bc5191

Author: Alexandros Frantzis <alexandros.frantzis at collabora.com>
Date:   Thu May 23 21:16:48 2019 +0300

virgl: Avoid unfinished transfer_get with PIPE_TRANSFER_DONTBLOCK

If we are not allowed to block, and we know that we will have to wait,
either because the resource is busy, or because it will become busy due
to a readback, return early to avoid performing an incomplete
transfer_get. Such an incomplete transfer_get may finish at any time,
during which another unsynchronized map could write to the resource
contents, leaving the contents in an undefined state.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
Suggested-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Chia-I Wu <olvaffe at gmail.com>

---

 src/gallium/drivers/virgl/virgl_resource.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c
index 8e3d6b38423..1cb9feb3658 100644
--- a/src/gallium/drivers/virgl/virgl_resource.c
+++ b/src/gallium/drivers/virgl/virgl_resource.c
@@ -147,21 +147,24 @@ virgl_resource_transfer_prepare(struct virgl_context *vctx,
    if (flush)
       vctx->base.flush(&vctx->base, NULL, 0);
 
+   /* If we are not allowed to block, and we know that we will have to wait,
+    * either because the resource is busy, or because it will become busy due
+    * to a readback, return early to avoid performing an incomplete
+    * transfer_get. Such an incomplete transfer_get may finish at any time,
+    * during which another unsynchronized map could write to the resource
+    * contents, leaving the contents in an undefined state.
+    */
+   if ((xfer->base.usage & PIPE_TRANSFER_DONTBLOCK) &&
+       (readback || (wait && vws->resource_is_busy(vws, res->hw_res))))
+      return VIRGL_TRANSFER_MAP_ERROR;
+
    if (readback) {
       vws->transfer_get(vws, res->hw_res, &xfer->base.box, xfer->base.stride,
                         xfer->l_stride, xfer->offset, xfer->base.level);
    }
 
-   if (wait) {
-      /* fail the mapping after flush and readback so that it will succeed in
-       * the future
-       */
-      if ((xfer->base.usage & PIPE_TRANSFER_DONTBLOCK) &&
-          vws->resource_is_busy(vws, res->hw_res))
-         return VIRGL_TRANSFER_MAP_ERROR;
-
+   if (wait)
       vws->resource_wait(vws, res->hw_res);
-   }
 
    return map_type;
 }




More information about the mesa-commit mailing list