Mesa (master): winsys/svga: Optionally avoid caching buffer maps

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Apr 29 14:05:08 UTC 2020


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

Author: Thomas Hellstrom <thellstrom at vmware.com>
Date:   Wed Apr 22 15:03:15 2020 +0200

winsys/svga: Optionally avoid caching buffer maps

Mapping of graphics kernel buffers is quite costly. Therefore the svga
drm winsys caches all kernel buffer maps. However, that may lead to
less testing coverage of the unmap paths and (possibly) processes running
out of virtual memory space. Introduce a possibility to avoid that caching
by setting the environment variable SVGA_FORCE_KERNEL_UNMAPS to 1.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Reviewed-by: Matthew McClure <mcclurem at vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4804>

---

 src/gallium/winsys/svga/drm/vmw_buffer.c       | 17 ++++++++++++++---
 src/gallium/winsys/svga/drm/vmw_screen.c       |  3 +++
 src/gallium/winsys/svga/drm/vmw_screen.h       |  1 +
 src/gallium/winsys/svga/drm/vmw_screen_ioctl.c | 13 ++++---------
 4 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.c b/src/gallium/winsys/svga/drm/vmw_buffer.c
index e2ddf78ed2e..03db92a6481 100644
--- a/src/gallium/winsys/svga/drm/vmw_buffer.c
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
@@ -63,6 +63,7 @@ struct vmw_gmr_buffer
    struct vmw_region *region;
    void *map;
    unsigned map_flags;
+   unsigned map_count;
 };
 
 
@@ -104,8 +105,12 @@ vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
 {
    struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
 
-   vmw_ioctl_region_unmap(buf->region);
-   
+   assert(buf->map_count == 0);
+   if (buf->map) {
+      assert(buf->mgr->vws->cache_maps);
+      vmw_ioctl_region_unmap(buf->region);
+   }
+
    vmw_ioctl_region_destroy(buf->region);
 
    FREE(buf);
@@ -126,7 +131,6 @@ vmw_gmr_buffer_map(struct pb_buffer *_buf,
    if (!buf->map)
       return NULL;
 
-
    if ((_buf->usage & VMW_BUFFER_USAGE_SYNC) &&
        !(flags & PB_USAGE_UNSYNCHRONIZED)) {
       ret = vmw_ioctl_syncforcpu(buf->region,
@@ -137,6 +141,7 @@ vmw_gmr_buffer_map(struct pb_buffer *_buf,
          return NULL;
    }
 
+   buf->map_count++;
    return buf->map;
 }
 
@@ -153,6 +158,12 @@ vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
                                !(flags & PB_USAGE_CPU_WRITE),
                                FALSE);
    }
+
+   assert(buf->map_count > 0);
+   if (!--buf->map_count && !buf->mgr->vws->cache_maps) {
+      vmw_ioctl_region_unmap(buf->region);
+      buf->map = NULL;
+   }
 }
 
 
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 8b4b89981b2..2f70212de61 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -67,6 +67,7 @@ vmw_winsys_create( int fd )
 {
    struct vmw_winsys_screen *vws;
    struct stat stat_buf;
+   const char *getenv_val;
 
    if (dev_hash == NULL) {
       dev_hash = _mesa_hash_table_create(NULL, vmw_dev_hash, vmw_dev_compare);
@@ -97,6 +98,8 @@ vmw_winsys_create( int fd )
    vws->base.have_gb_dma = !vws->force_coherent;
    vws->base.need_to_rebind_resources = FALSE;
    vws->base.have_transfer_from_buffer_cmd = vws->base.have_vgpu10;
+   getenv_val = getenv("SVGA_FORCE_KERNEL_UNMAPS");
+   vws->cache_maps = !getenv_val || strcmp(getenv_val, "0") == 0;
    vws->fence_ops = vmw_fence_ops_create(vws);
    if (!vws->fence_ops)
       goto out_no_fence_ops;
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index c55de4a2b6f..4cf6b3fd895 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -108,6 +108,7 @@ struct vmw_winsys_screen
    mtx_t cs_mutex;
 
    boolean force_coherent;
+   boolean cache_maps;
 };
 
 
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 9696f884e4f..bb3a1adedc1 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -64,7 +64,6 @@ struct vmw_region
    uint32_t handle;
    uint64_t map_handle;
    void *data;
-   uint32_t map_count;
    int drm_fd;
    uint32_t size;
 };
@@ -637,7 +636,6 @@ vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
    region->data = NULL;
    region->handle = rep->handle;
    region->map_handle = rep->map_handle;
-   region->map_count = 0;
    region->size = size;
    region->drm_fd = vws->ioctl.drm_fd;
 
@@ -659,10 +657,7 @@ vmw_ioctl_region_destroy(struct vmw_region *region)
    vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
               region->ptr.gmrId, region->ptr.offset);
 
-   if (region->data) {
-      os_munmap(region->data, region->size);
-      region->data = NULL;
-   }
+   assert(region->data == NULL);
 
    memset(&arg, 0, sizeof(arg));
    arg.handle = region->handle;
@@ -701,8 +696,6 @@ vmw_ioctl_region_map(struct vmw_region *region)
       region->data = map;
    }
 
-   ++region->map_count;
-
    return region->data;
 }
 
@@ -711,7 +704,9 @@ vmw_ioctl_region_unmap(struct vmw_region *region)
 {
    vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
               region->ptr.gmrId, region->ptr.offset);
-   --region->map_count;
+
+   os_munmap(region->data, region->size);
+   region->data = NULL;
 }
 
 /**



More information about the mesa-commit mailing list