On Thu, Jul 12, 2018 at 5:24 PM, Felix Kuehling <Felix.Kuehling at amd.com> wrote: > From: Yong Zhao <yong.zhao at amd.com> > > 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 at amd.com> > Reviewed-by: Felix Kuehling <Felix.Kuehling at amd.com> > Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com> Acked-by: Alex Deucher <alexander.deucher at amd.com> > --- > drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 57 ++++++++++++++++++++++++++++------- > 1 file changed, 46 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > index 296b3f2..ee49960 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c > @@ -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); > -- > 2.7.4 > > _______________________________________________ > amd-gfx mailing list > amd-gfx at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx