[Mesa-dev] [PATCH v2 2/2] anv: Advertise larger heap sizes

Kristian H. Kristensen krh at bitplanet.net
Thu Mar 30 16:28:48 UTC 2017


Jason Ekstrand <jason at jlekstrand.net> writes:

> Instead of just advertising the aperture size, we do something more
> intelligent.  On systems with a full 48-bit PPGTT, we can address 100%
> of the available system RAM from the GPU.  In order to keep clients from
> burning 100% of your available RAM for graphics resources, we have a
> nice little heuristic (which has received exactly zero tuning) to keep
> things under a reasonable level of control.
>
> Cc: Alex Smith <asmith at feralinteractive.com>

Looks entirely reasonable, and yes, you'll probably have to tune it as
you go :)

Reviewed-by: Kristian H. Kristensen <krh at bitplanet.net>

> ---
>  src/intel/vulkan/anv_device.c  | 61 +++++++++++++++++++++++++++++++++---------
>  src/intel/vulkan/anv_gem.c     | 16 +++++++++++
>  src/intel/vulkan/anv_private.h | 13 ++++++++-
>  3 files changed, 76 insertions(+), 14 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index f9d04ee..0e5e4b9 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -25,6 +25,7 @@
>  #include <stdbool.h>
>  #include <string.h>
>  #include <sys/mman.h>
> +#include <sys/sysinfo.h>
>  #include <unistd.h>
>  #include <fcntl.h>
>  #include <xf86drm.h>
> @@ -53,6 +54,48 @@ compiler_perf_log(void *data, const char *fmt, ...)
>     va_end(args);
>  }
>  
> +static VkResult
> +anv_compute_heap_size(int fd, uint64_t *heap_size)
> +{
> +   uint64_t gtt_size;
> +   if (anv_gem_get_context_param(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE,
> +                                 &gtt_size) == -1) {
> +      /* If, for whatever reason, we can't actually get the GTT size from the
> +       * kernel (too old?) fall back to the aperture size.
> +       */
> +      anv_perf_warn("Failed to get I915_CONTEXT_PARAM_GTT_SIZE: %m");
> +
> +      if (anv_gem_get_aperture(fd, &gtt_size) == -1) {
> +         return vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
> +                          "failed to get aperture size: %m");
> +      }
> +   }
> +
> +   /* Query the total ram from the system */
> +   struct sysinfo info;
> +   sysinfo(&info);
> +
> +   uint64_t total_ram = (uint64_t)info.totalram * (uint64_t)info.mem_unit;
> +
> +   /* We don't want to burn too much ram with the GPU.  If the user has 4GiB
> +    * or less, we use at most half.  If they have more than 4GiB, we use 3/4.
> +    */
> +   uint64_t available_ram;
> +   if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
> +      available_ram = total_ram / 2;
> +   else
> +      available_ram = total_ram * 3 / 4;
> +
> +   /* We also want to leave some padding for things we allocate in the driver,
> +    * so don't go over 3/4 of the GTT either.
> +    */
> +   uint64_t available_gtt = gtt_size * 3 / 4;
> +
> +   *heap_size = MIN2(available_ram, available_gtt);
> +
> +   return VK_SUCCESS;
> +}
> +
>  static bool
>  anv_device_get_cache_uuid(void *uuid)
>  {
> @@ -124,12 +167,6 @@ anv_physical_device_init(struct anv_physical_device *device,
>        }
>     }
>  
> -   if (anv_gem_get_aperture(fd, &device->aperture_size) == -1) {
> -      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
> -                         "failed to get aperture size: %m");
> -      goto fail;
> -   }
> -
>     if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) {
>        result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
>                           "kernel missing gem wait");
> @@ -151,6 +188,10 @@ anv_physical_device_init(struct anv_physical_device *device,
>  
>     device->supports_48bit_addresses = anv_gem_supports_48b_addresses(fd);
>  
> +   result = anv_compute_heap_size(fd, &device->heap_size);
> +   if (result != VK_SUCCESS)
> +      goto fail;
> +
>     if (!anv_device_get_cache_uuid(device->uuid)) {
>        result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
>                           "cannot generate UUID");
> @@ -731,12 +772,6 @@ void anv_GetPhysicalDeviceMemoryProperties(
>      VkPhysicalDeviceMemoryProperties*           pMemoryProperties)
>  {
>     ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
> -   VkDeviceSize heap_size;
> -
> -   /* Reserve some wiggle room for the driver by exposing only 75% of the
> -    * aperture to the heap.
> -    */
> -   heap_size = 3 * physical_device->aperture_size / 4;
>  
>     if (physical_device->info.has_llc) {
>        /* Big core GPUs share LLC with the CPU and thus one memory type can be
> @@ -773,7 +808,7 @@ void anv_GetPhysicalDeviceMemoryProperties(
>  
>     pMemoryProperties->memoryHeapCount = 1;
>     pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
> -      .size = heap_size,
> +      .size = physical_device->heap_size,
>        .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
>     };
>  }
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index 3d45243..5f478b5 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -288,6 +288,22 @@ anv_gem_destroy_context(struct anv_device *device, int context)
>  }
>  
>  int
> +anv_gem_get_context_param(int fd, int context, uint32_t param, uint64_t *value)
> +{
> +   struct drm_i915_gem_context_param gp = {
> +      .ctx_id = context,
> +      .param = param,
> +   };
> +
> +   int ret = anv_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &gp);
> +   if (ret == -1)
> +      return -1;
> +
> +   *value = gp.value;
> +   return 0;
> +}
> +
> +int
>  anv_gem_get_aperture(int fd, uint64_t *size)
>  {
>     struct drm_i915_gem_get_aperture aperture = { 0 };
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index 425e376..0169796 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -543,7 +543,16 @@ struct anv_physical_device {
>      char                                        path[20];
>      const char *                                name;
>      struct gen_device_info                      info;
> -    uint64_t                                    aperture_size;
> +    /** Amount of "GPU memory" we want to advertise
> +     *
> +     * Clearly, this value is bogus since Intel is a UMA architecture.  On
> +     * gen7 platforms, we are limited by GTT size unless we want to implement
> +     * fine-grained tracking and GTT splitting.  On Broadwell and above we are
> +     * practically unlimited.  However, we will never report more than 3/4 of
> +     * the total system ram to try and avoid running out of RAM.
> +     */
> +    uint64_t                                    heap_size;
> +    bool                                        supports_48bit_addresses;
>      struct brw_compiler *                       compiler;
>      struct isl_device                           isl_dev;
>      int                                         cmd_parser_version;
> @@ -675,6 +684,8 @@ int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle,
>                         uint32_t stride, uint32_t tiling);
>  int anv_gem_create_context(struct anv_device *device);
>  int anv_gem_destroy_context(struct anv_device *device, int context);
> +int anv_gem_get_context_param(int fd, int context, uint32_t param,
> +                              uint64_t *value);
>  int anv_gem_get_param(int fd, uint32_t param);
>  bool anv_gem_get_bit6_swizzle(int fd, uint32_t tiling);
>  int anv_gem_get_aperture(int fd, uint64_t *size);
> -- 
> 2.5.0.400.gff86faf
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list