]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
drm/amdkfd: Consolidate duplicate memory banks info in topology
authorYong Zhao <yong.zhao@amd.com>
Fri, 13 Jul 2018 20:17:43 +0000 (16:17 -0400)
committerOded Gabbay <oded.gabbay@gmail.com>
Fri, 13 Jul 2018 20:17:43 +0000 (16:17 -0400)
If there are several memory banks that has the same properties in CRAT,
we aggregate them into one memory bank. This cleans up memory banks on
APUs (e.g. Raven) where the CRAT reports each memory channel as a
separate bank. This only confuses user mode, which only deals with
virtual memory.

Signed-off-by: Yong Zhao <yong.zhao@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
drivers/gpu/drm/amd/amdkfd/kfd_crat.c

index 296b3f230280bc8def89b6d7b700995f1ec6dcc1..ee4996029a86866fc05807e60ec956e2ddad80df 100644 (file)
@@ -189,6 +189,21 @@ static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu,
        return 0;
 }
 
+static struct kfd_mem_properties *
+find_subtype_mem(uint32_t heap_type, uint32_t flags, uint32_t width,
+               struct kfd_topology_device *dev)
+{
+       struct kfd_mem_properties *props;
+
+       list_for_each_entry(props, &dev->mem_props, list) {
+               if (props->heap_type == heap_type
+                               && props->flags == flags
+                               && props->width == width)
+                       return props;
+       }
+
+       return NULL;
+}
 /* kfd_parse_subtype_mem - parse memory subtypes and attach it to correct
  * topology device present in the device_list
  */
@@ -197,36 +212,56 @@ static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem,
 {
        struct kfd_mem_properties *props;
        struct kfd_topology_device *dev;
+       uint32_t heap_type;
+       uint64_t size_in_bytes;
+       uint32_t flags = 0;
+       uint32_t width;
 
        pr_debug("Found memory entry in CRAT table with proximity_domain=%d\n",
                        mem->proximity_domain);
        list_for_each_entry(dev, device_list, list) {
                if (mem->proximity_domain == dev->proximity_domain) {
-                       props = kfd_alloc_struct(props);
-                       if (!props)
-                               return -ENOMEM;
-
                        /* We're on GPU node */
                        if (dev->node_props.cpu_cores_count == 0) {
                                /* APU */
                                if (mem->visibility_type == 0)
-                                       props->heap_type =
+                                       heap_type =
                                                HSA_MEM_HEAP_TYPE_FB_PRIVATE;
                                /* dGPU */
                                else
-                                       props->heap_type = mem->visibility_type;
+                                       heap_type = mem->visibility_type;
                        } else
-                               props->heap_type = HSA_MEM_HEAP_TYPE_SYSTEM;
+                               heap_type = HSA_MEM_HEAP_TYPE_SYSTEM;
 
                        if (mem->flags & CRAT_MEM_FLAGS_HOT_PLUGGABLE)
-                               props->flags |= HSA_MEM_FLAGS_HOT_PLUGGABLE;
+                               flags |= HSA_MEM_FLAGS_HOT_PLUGGABLE;
                        if (mem->flags & CRAT_MEM_FLAGS_NON_VOLATILE)
-                               props->flags |= HSA_MEM_FLAGS_NON_VOLATILE;
+                               flags |= HSA_MEM_FLAGS_NON_VOLATILE;
 
-                       props->size_in_bytes =
+                       size_in_bytes =
                                ((uint64_t)mem->length_high << 32) +
                                                        mem->length_low;
-                       props->width = mem->width;
+                       width = mem->width;
+
+                       /* Multiple banks of the same type are aggregated into
+                        * one. User mode doesn't care about multiple physical
+                        * memory segments. It's managed as a single virtual
+                        * heap for user mode.
+                        */
+                       props = find_subtype_mem(heap_type, flags, width, dev);
+                       if (props) {
+                               props->size_in_bytes += size_in_bytes;
+                               break;
+                       }
+
+                       props = kfd_alloc_struct(props);
+                       if (!props)
+                               return -ENOMEM;
+
+                       props->heap_type = heap_type;
+                       props->flags = flags;
+                       props->size_in_bytes = size_in_bytes;
+                       props->width = width;
 
                        dev->node_props.mem_banks_count++;
                        list_add_tail(&props->list, &dev->mem_props);