Module: Mesa Branch: master Commit: 298e247776309b4444b4c3ac26872fc1f694568c URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=298e247776309b4444b4c3ac26872fc1f694568c
Author: Thomas Hellstrom <[email protected]> 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 <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]> Reviewed-by: Matthew McClure <[email protected]> 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; } /** _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
