On 2025-02-05 15:36, Mario Limonciello wrote: > On 2/5/2025 14:33, Felix Kuehling wrote: >> >> >> On 2025-02-05 14:31, Mario Limonciello wrote: >>> On 2/4/2025 17:19, Felix Kuehling wrote: >>>> >>>> On 2025-02-04 17:21, Mario Limonciello wrote: >>>>> From: Mario Limonciello <mario.limoncie...@amd.com> >>>>> >>>>> find_system_memory() pulls out two fields from an SMBIOS type 17 >>>>> device and sets them on KFD devices. This however is pulling from >>>>> the middle of the field in the SMBIOS device and leads to an unaligned >>>>> access. >>>>> >>>>> Instead use a struct representation to access the members and pull >>>>> out the two specific fields. >>>> >>>> Isn't that still an unaligned access? I don't understand the purpose of >>>> this patch. >>> >>> Unless I added wrong, it looked to me that the offset it was pulling from >>> previously was incorrect. So I was expecting it should be aligned (and >>> less error prone) to pull from the correct offset from a struct. >> >> The way I see it, the offsets that were used before were correct and match >> the offsets in the packed structure definition. I'm annotating the offsets >> from the end of the header in the structure definition below as proof. >> > > The problem I saw was that the dmi_data field starts a byte late though. > That's why I was thinking this is the source of the unaligned access and the > mistake. > > Let me annotate below. > >>> >>>> >>>> One more comment inline. >>>> >>>>> >>>>> Link: >>>>> https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.8.0.pdf >>>>> p99 >>>>> Signed-off-by: Mario Limonciello <mario.limoncie...@amd.com> >>>>> --- >>>>> drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 27 +++++++++++------------ >>>>> drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 17 ++++++++++++++ >>>>> 2 files changed, 30 insertions(+), 14 deletions(-) >>>>> >>>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c >>>>> b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c >>>>> index ceb9fb475ef13..93d3924dfcba0 100644 >>>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c >>>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c >>>>> @@ -968,24 +968,23 @@ static void kfd_update_system_properties(void) >>>>> up_read(&topology_lock); >>>>> } >>>>> -static void find_system_memory(const struct dmi_header *dm, >>>>> - void *private) >>>>> +static void find_system_memory(const struct dmi_header *dm, void >>>>> *private) >>>>> { >>>>> + struct dmi_mem_device *memdev = (struct dmi_mem_device *)(dm); >>>> >>>> I think it would be cleaner to use container_of to get a pointer to the >>>> structure containing the header. >>> >>> Ack. >>> >>>> >>>> Regards, >>>> Felix >>>> >>>>> struct kfd_mem_properties *mem; >>>>> - u16 mem_width, mem_clock; >>>>> struct kfd_topology_device *kdev = >>>>> (struct kfd_topology_device *)private; >>>>> - const u8 *dmi_data = (const u8 *)(dm + 1); > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The type of dm is struct dmi_header *. dm + 1 is the first byte after the dmi_header. In other words dmi_data points to the physical_handle field, which is the field with offset 0 as I annotated it below and all the other offsets match my annotations, which match the original code. Regards, Felix >>>>> - >>>>> - if (dm->type == DMI_ENTRY_MEM_DEVICE && dm->length >= 0x15) { >>>>> - mem_width = (u16)(*(const u16 *)(dmi_data + 0x6)); >>>>> - mem_clock = (u16)(*(const u16 *)(dmi_data + 0x11)); >>>>> - list_for_each_entry(mem, &kdev->mem_props, list) { >>>>> - if (mem_width != 0xFFFF && mem_width != 0) >>>>> - mem->width = mem_width; >>>>> - if (mem_clock != 0) >>>>> - mem->mem_clk_max = mem_clock; >>>>> - } >>>>> + >>>>> + if (memdev->header.type != DMI_ENTRY_MEM_DEVICE) >>>>> + return; >>>>> + if (memdev->header.length < sizeof(struct dmi_mem_device)) >>>>> + return; >>>>> + >>>>> + list_for_each_entry(mem, &kdev->mem_props, list) { >>>>> + if (memdev->total_width != 0xFFFF && memdev->total_width != 0) >>>>> + mem->width = memdev->total_width; >>>>> + if (memdev->speed != 0) >>>>> + mem->mem_clk_max = memdev->speed; >>>>> } >>>>> } >>>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h >>>>> b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h >>>>> index 155b5c410af16..f06c9db7ddde9 100644 >>>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.h >>>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.h >>>>> @@ -24,6 +24,7 @@ >>>>> #ifndef __KFD_TOPOLOGY_H__ >>>>> #define __KFD_TOPOLOGY_H__ >>>>> +#include <linux/dmi.h> >>>>> #include <linux/types.h> >>>>> #include <linux/list.h> >>>>> #include <linux/kfd_sysfs.h> >>>>> @@ -179,6 +180,22 @@ struct kfd_system_properties { >>>>> struct attribute attr_props; >>>>> }; >>>>> +struct dmi_mem_device { >>>>> + struct dmi_header header; >> >> Comments below to annotate the byte offset of each field from the end of the >> header. >> >>>>> + u16 physical_handle; // 0x0 >>>>> + u16 error_handle; // 0x2 >>>>> + u16 total_width; // 0x4 >>>>> + u16 data_width; // 0x6 (matches the original code) >>>>> + u16 size; // 0x8 >>>>> + u8 form_factor; // 0xa >>>>> + u8 device_set; // 0xb >>>>> + u8 device_locator; // 0xc >>>>> + u8 bank_locator; // 0xd >>>>> + u8 memory_type; // 0xe >>>>> + u16 type_detail; // 0xf >>>>> + u16 speed; // 0x11 (matches the original code) >>>>> +} __packed; >> >> The bottom line is, this patch doesn't change anything about which DMI data >> is accessed. It's still an unaligned access. Now I think your patch is still >> a decent cleanup. But the justification in the commit description doesn't >> make sense. >> >> Regards, >> Felix >> >>>>> + >>>>> struct kfd_topology_device *kfd_create_topology_device( >>>>> struct list_head *device_list); >>>>> void kfd_release_topology_device_list(struct list_head *device_list); >>>> >>> >> >