drm/amdgpu: Adjust the VM size based on system memory size v2
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_vm.c
index 7e644bc..b905d79 100644 (file)
@@ -2504,28 +2504,52 @@ static uint32_t amdgpu_vm_get_block_size(uint64_t vm_size)
  * amdgpu_vm_adjust_size - adjust vm size, block size and fragment size
  *
  * @adev: amdgpu_device pointer
- * @vm_size: the default vm size if it's set auto
+ * @min_vm_size: the minimum vm size in GB if it's set auto
  * @fragment_size_default: Default PTE fragment size
  * @max_level: max VMPT level
  * @max_bits: max address space size in bits
  *
  */
-void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t vm_size,
+void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
                           uint32_t fragment_size_default, unsigned max_level,
                           unsigned max_bits)
 {
+       unsigned int max_size = 1 << (max_bits - 30);
+       unsigned int vm_size;
        uint64_t tmp;
 
        /* adjust vm size first */
        if (amdgpu_vm_size != -1) {
-               unsigned max_size = 1 << (max_bits - 30);
-
                vm_size = amdgpu_vm_size;
                if (vm_size > max_size) {
                        dev_warn(adev->dev, "VM size (%d) too large, max is %u GB\n",
                                 amdgpu_vm_size, max_size);
                        vm_size = max_size;
                }
+       } else {
+               struct sysinfo si;
+               unsigned int phys_ram_gb;
+
+               /* Optimal VM size depends on the amount of physical
+                * RAM available. Underlying requirements and
+                * assumptions:
+                *
+                *  - Need to map system memory and VRAM from all GPUs
+                *     - VRAM from other GPUs not known here
+                *     - Assume VRAM <= system memory
+                *  - On GFX8 and older, VM space can be segmented for
+                *    different MTYPEs
+                *  - Need to allow room for fragmentation, guard pages etc.
+                *
+                * This adds up to a rough guess of system memory x3.
+                * Round up to power of two to maximize the available
+                * VM size with the given page table size.
+                */
+               si_meminfo(&si);
+               phys_ram_gb = ((uint64_t)si.totalram * si.mem_unit +
+                              (1 << 30) - 1) >> 30;
+               vm_size = roundup_pow_of_two(
+                       min(max(phys_ram_gb * 3, min_vm_size), max_size));
        }
 
        adev->vm_manager.max_pfn = (uint64_t)vm_size << 18;